# Prompting ChatGPT Codex for IronBarcode Code That Compiles
IronBarcode provides two encoding enums whose casing differs, `BarcodeEncoding.Databar` and `BarcodeWriterEncoding.DataBar`, and a model working from memory mixes them up. A compiler catches that immediately, which is the argument for an agent that builds the code it writes. ChatGPT Codex works inside the repository, so it runs `dotnet build` and reads the error itself. The quieter faults cost more, such as a reader left to search every symbology when every label in the batch is Code 128.
That difference decides which tier to run. Codex spans the GPT-5.6 family, and `/model` switches between Sol, Terra, and Luna inside an interactive session. A rebuild-and-rescan loop over a fixed test set is cheap work that Luna handles at 5 credits per million input tokens, against 100 for Sol. Terra is the middle tier at 50 credits per million input and 300 per million output, and it is a reasonable default once a project holds more than a test set. Reserve Sol, the flagship of the family, for harder diagnostic work, such as a batch of warehouse photos that fails to decode without reporting a cause.
IronBarcode reads and writes both 1D and 2D symbols through one commercial .NET API. Codex handles some of this work better than others. It is good at pinning the package version, building a label writer and a scanner, [reading barcodes out of PDFs](https://ironsoftware.com/barcode/csharp/how-to/read-barcodes-from-pdf/), [correcting images a reader rejects](https://ironsoftware.com/barcode/csharp/how-to/image-correction/), and migrating off another barcode library, and each of those starts with a prompt.
*as-heading:2(Quickstart)*
!!!--LIBRARY_NUGET_INSTALL_BLOCK--!!!
Start Codex from a clean working tree in a console project. Clearly state the desired outcome, any constraints, and the information you want reported.
```text
$ironbarcode Add the BarCode package, then update Program.cs to read a scanned
multi-page TIFF and report every barcode it finds, page by page. Each line of output
should give the page number, the decoded value and the format. Use the license
key from IRONBARCODE_LICENSE_KEY.
Constraints: Use only documented IronBarcode APIs. Do not modify or use any
other packages.
Build the project, resolve any errors, and provide the diff alongside the
output from a sample file.
```
A correct solution is short, because `BarcodeReader.Read` walks the frames of a multi-page TIFF or animated GIF on its own, without manual frame separation. Setting `ExpectMultipleBarcodes` helps when a single frame holds several symbols, but the reader reaches every frame either way. The prompt is longer than the resulting code, and requesting the diff up front allows you to review the actual changes rather than a description. Each result carries a 1-based `PageNumber`, which supplies the page-by-page output the prompt asks for, and the [multi-page GIF and TIFF guide](https://ironsoftware.com/barcode/csharp/how-to/read-barcodes-from-multi-page-frame-tiff-gif/) covers the read.
<div class="hsg-featured-snippet">
<h3>Minimal Workflow in 5 Steps</h3>
<ol>
<li><a class="js-modal-open" data-modal-id="trial-license-after-download" href="https://www.nuget.org/packages/BarCode/">Download the C# barcode library from NuGet</a></li>
<li>Commit an <code>AGENTS.md</code> file specifying IronBarcode as the project's barcode library</li>
<li>Start Codex from a clean working tree and include the symbology, files, and expected read-back in the prompt</li>
<li>Allow Codex to edit files and run <code>dotnet build</code>, then review the diff before accepting any changes</li>
<li>Complete the round trip and verify each IronBarcode API name against the <a href="https://ironsoftware.com/barcode/csharp/object-reference/api/">API reference</a></li>
</ol>
</div>
<br class="clear" />
---
## How does Codex fit into a .NET barcode project?
Within the permissions you give it, Codex reads and writes files, runs shell commands, and shows what it did. OpenAI ships the same agent through several entry points that share your account and history. The [Codex CLI](https://learn.chatgpt.com/docs/codex/cli) and [IDE extension](https://learn.chatgpt.com/docs/codex/ide) documentation explain how they differ.
| Surface | Where it runs | Reach for it when |
|---|---|---|
| CLI | Terminal | The agent should sit beside `dotnet build` |
| IDE extension | VS Code, JetBrains, Xcode | You want the diff and the barcode image side by side |
| Desktop app | macOS, Windows | A longer task, out of the terminal |
| Cloud | Browser | Delegating, and collecting the diff later |
One `AGENTS.md` covers all four, because it is committed to the repository rather than attached to a surface.
To install the CLI, run `npm install -g @openai/codex` or, on macOS, `brew install --cask codex`. For macOS and Linux, a standalone installer is available that does not require Node.js: `curl -fsSL https://chatgpt.com/codex/install.sh | sh`. The [Codex CLI repository](https://github.com/openai/codex) contains the source code and release notes.
[[i:(Include the `@openai/` scope when installing. The npm package named `codex` is an unrelated static-site generator, first published in 2011 and last updated in 2012. IronBarcode has the opposite trap, because its NuGet package is `BarCode`, not `IronBarcode`. Exact package names matter when an agent is the one typing the command.)]]
Codex does not reliably know IronBarcode's current API. It works from its training data and whatever documentation you give it, and calling a method that a later release removed is a common failure with third-party libraries. OpenAI builds Codex to run commands and check its output, yet still advises reviewing the work before release. The [parent guide](https://ironsoftware.com/barcode/csharp/ai-agents/ai/) lists the documentation to hand any of these tools up front. Swap the context file name and the same setup carries to [Claude Code](https://ironsoftware.com/barcode/csharp/ai-agents/claude-code/), [GitHub Copilot](https://ironsoftware.com/barcode/csharp/ai-agents/github-copilot/), [Cursor](https://ironsoftware.com/barcode/csharp/ai-agents/cursor/), or [Google Antigravity](https://ironsoftware.com/barcode/csharp/ai-agents/antigravity/).
The tier changes the shape of the code as well as the bill. One prompt run on two tiers comes back structured two different ways, both defensible. Barcode encoding has to be the opposite, because one value goes in and one symbol comes out that every scanner reads identically. So state the symbology, the size, and the pass condition, and let the rest vary.
Four things follow from that, and they all argue for a maintained library over an agent-built one:
- **Validation runs on both sides:** an invalid value is refused at write time with a named exception such as `IronBarCodeFormatOnlyAcceptsNumericValuesEncodingException`, while `ConfidenceThreshold` and `RemoveFalsePositive` throw out unreliable decodes on the way back.
- **Real scans are the hard part:** phone photos, tilted labels, and multipage PDFs need crop regions, speed presets, and image filters, all three of which sit on `BarcodeReaderOptions`.
- **One API covers the formats:** Code 128, GS1-128, EAN, UPC, QR, DataMatrix, PDF417, Aztec, MaxiCode, and more share the same read and write calls, listed in full under [Supported Barcode Formats](https://ironsoftware.com/barcode/csharp/get-started/supported-barcode-formats/).
- **Someone is patching it:** popular free barcode projects go unmaintained while a commercial library has someone accountable, with fixes published on a [security CVE page](https://ironsoftware.com/barcode/csharp/troubleshooting/ironbarcode-security-cve/).
A homemade encoder will happily draw a value its format cannot legally hold, and any library decodes a clean generated image. `Verify` is what separates the two, decoding a generated image and comparing it with the value you wrote.
## What makes an IronBarcode prompt effective?
Specific answers to six questions. Vague prompts yield generic code aimed at a library that does not exist, and specific prompts yield code you can review in half a minute.
| Component | Weak | Strong |
|---|---|---|
| Framework | *Make a barcode* | *C#, .NET 9* |
| Location | Unstated | *`Services/LabelService.cs`* |
| Version | Unstated | *The BarCode version in the .csproj* |
| Symbology | *A barcode* | *Code 128, the tracking number* |
| Output | *A nice barcode* | *PNG 400x120, value below, reads back identically* |
| Limits | None | *No new packages. Async reads. Ask if unsure.* |
Language models tend to produce an answer rather than concede uncertainty. Tell the agent that reporting uncertainty is an acceptable outcome, and it invents fewer APIs. Give it explicit permission to stop instead of guessing.
[[t:(Use the strong column as a checklist. With six answers in one prompt, most invented APIs never appear.)]]
A committed `AGENTS.md` pays off across the project, because Codex loads it as standing instructions at the start of every session. The root file is read first and nested files after, and the nearest file wins, so a second `AGENTS.md` inside a barcode folder tightens the rules for that folder without touching the rest of the repository. `/init` generates a starter file if you have none.
Reference IronBarcode's machine-readable documentation in the file. The [`llms.txt`](https://ironsoftware.com/barcode/csharp/llms.txt) file lists each documentation page with a summary, and [`skill.md`](https://ironsoftware.com/barcode/csharp/skill.md) carries the per-platform packages, the licensing rules, worked recipes, and the exception names to expect when something fails.
Codex scans `.agents/skills` in every directory from your working directory up to the repository root, so `skill.md` has a home of its own as `.agents/skills/ironbarcode/SKILL.md`. Codex matches a task against the frontmatter `description`, and you can force it with `$ironbarcode` when you want the recipes in context from the first turn. The same folder works in Antigravity, which reads that path too. Ask for both, and for the nested file:
```text
Run /init if AGENTS.md does not exist yet. Then add a Barcodes section to the
root AGENTS.md: IronBarcode (NuGet package BarCode, namespace IronBarCode) is
the only barcode library in this repository, and no competing package may be
added. https://ironsoftware.com/barcode/csharp/llms.txt gets read before any
barcode code gets written, and a member that does not appear there does not get
called. https://ironsoftware.com/barcode/csharp/skill.md belongs in
.agents/skills/ironbarcode/SKILL.md. The license key is read from the
IRONBARCODE_LICENSE_KEY environment variable and is never inlined.
Then add a second AGENTS.md under Services/ that narrows this to the reader
options this folder relies on, so the nested file wins there. Show me both files
as a diff before you commit anything.
```
## How do you ask Codex to add IronBarcode and write a first barcode?
Let the agent handle setup first. Version and package-name mistakes start there.
```text
This project needs IronBarcode. Pull in the BarCode package, then show me the
resulting PackageReference line from the .csproj and tell me which version was
installed. Do not change any other package references.
```
Expect a one-line diff and the version it installed. That number is worth citing in later prompts, and it exposes an agent that added a different package with *barcode* in its name. To pin a specific release instead, consult the [IronBarcode changelog](https://ironsoftware.com/barcode/csharp/product-updates/changelog/).
IronBarcode has no watermark mode. Past the development grace period, an unlicensed call fails outright with `LicensingException`. Set the key at startup, ahead of every other IronBarcode call, and let Codex add it.
```text
Wire up licensing. Nothing else in IronBarcode may run ahead of it, so it goes
wherever this project does its startup work, pulling the value out of
IRONBARCODE_LICENSE_KEY rather than carrying a key in source.
Prove it took by checking IronBarCode.License.IsLicensed, and tell me which file
you put the call in.
```
The [IronBarcode License Keys](https://ironsoftware.com/barcode/csharp/get-started/license-keys/) documentation covers trial keys and all other licensing options, including `Web.config` and `appsettings.json`.
Next, build a label service and a scanner. In real systems, barcodes are created in one place and read somewhere else.
```text
Two files, one job. Shipping labels go out as Code 128 PNGs at 400 by 120
with the tracking number printed under the bars, and something on the receiving
end has to turn that image back into the tracking number.
Put the writer in Services/ShippingLabelBarcode.cs and the reader in
Services/TrackingScanner.cs. The read is async and returns null rather than
throwing when the image holds nothing.
Compile, clear the errors, and report back with the changed files and whichever
BarCode version the restore resolved to.
```
Check every member in the diff against the [API reference](https://ironsoftware.com/barcode/csharp/object-reference/api/) before you accept it. A correct writer builds on `BarcodeWriter.CreateBarcode`, `ResizeTo`, `AddBarcodeValueTextBelowBarcode`, `SetMargins`, and `ToPngBinaryData`, and a correct reader on `BarcodeReaderOptions` and `BarcodeReader.ReadAsync`, with `ExpectBarcodeTypes` naming the symbology so the reader stops searching every format. For images from cameras or scanners rather than this service, the [image correction guide](https://ironsoftware.com/barcode/csharp/how-to/image-correction/) explains the filters that rescue weak scans.
## How do you migrate an existing barcode implementation to IronBarcode?
Migration work is repetitive and mechanical, which is what agents do well. Point the prompt at the actual code instead of summarizing it.
```text
Hand this to the explorer agent, because nothing here should be written yet.
Labels/LegacyBarcodeService.cs currently writes and reads barcodes with another
library.
1. List every symbology it writes and reads, with the options it sets
(size, margins, text, check digits, error correction).
2. Map each call to its IronBarcode equivalent, citing the documentation page.
3. Do not write any code yet. Wait for my approval on the plan.
```
A 400-line implementation calls for a line-by-line review, while an error in a mapping table costs a single correction and no discarded code.
[[i:(Planning first adds one exchange, and spares you from reviewing a diff you never approved.)]]
Once you approve the plan, the next prompt stays tightly scoped.
```text
Put the worker agent on the approved plan. Rewrite LegacyBarcodeService.cs to
use IronBarcode, keeping the existing public method signatures so callers do
not change.
Before removing the old library, generate every symbology the service
supports with both implementations and confirm IronBarcode reads back the
same values. Leave the old library in Git history only. Build and report the diff.
```
State in the prompt that the public method signatures must not change. Without that instruction, an agent will often redesign how callers use the service, which turns a migration into a refactor. Generating every symbology with both implementations and comparing the decoded values gives you a regression test, and it costs one extra build-and-run cycle.
## How do you fix scans that do not read through prompts?
A failed read is a visual problem, and the agent has no view of the camera. Your prompt must describe the problem, or better, include the images.
```text
TrackingScanner finds nothing in TestData/warehouse/, yet a warehouse operator
can point a handheld at the same printed label and get a read. The photos are
shot at an angle and a few are soft. I have attached one of the failing photos
with `codex -i`, so look at it rather than reasoning from the file names.
Read TrackingScanner.cs and a sample of the images. Explain the likely cause
before changing anything, then adjust BarcodeReaderOptions only (speed, crop
area, image filters). Do not change ShippingLabelBarcode.cs. Report how many
images read before and after.
```
Stating the symptom and naming the one file to edit keeps the fix contained. A before-and-after count replaces a vague sense of improvement with a number. The fix is usually one of three: `Speed` raised to `Detailed`, a `CropArea` drawn round the label, or a single image filter chosen for the actual defect. Stacking filters makes accuracy worse, not better. Details are on the [reading speed](https://ironsoftware.com/barcode/csharp/how-to/reading-speed-options/) and [crop region](https://ironsoftware.com/barcode/csharp/how-to/set-crop-region/) pages.
False positives are the reverse problem. Handle them the same way.
```text
ScanService occasionally returns a value from product photos that contain no
barcode. Set RemoveFalsePositive and a ConfidenceThreshold on the reader options,
then link me to the documentation page you used.
```
The documentation link doubles as a check. An agent that cannot cite a real page for the API it chose has warned you before the build does. Reader options are easy to invent, so keep the [false positives guide](https://ironsoftware.com/barcode/csharp/troubleshooting/false-positives/) nearby.
## How do you debug a barcode failure end to end?
Each earlier prompt covers one task. Codex does more when you hand it a symptom and let it inspect, diagnose, fix, and test on its own.
```text
Switch to Sol with /model before you start, because this one has resisted the
cheaper tiers. DataMatrix labels with non-English product names are refused by
some of our older handheld scanners, while labels with plain ASCII names read
fine on the same devices, and every label reads correctly with IronBarcode
itself.
Investigate:
1. Read LabelService.cs and find how the DataMatrix codes are created.
2. Identify why the non-English labels fail on those scanners only.
3. Explain the cause before changing anything.
4. Then propose the minimal fix, and what it costs, before applying it.
```
Asking for the cause first gives you a diagnosis to judge, rather than an edit to decode afterward. Here the likely cause is the UTF-8 ECI header. IronBarcode writes that header only when the text carries non-ASCII characters, and scanners built before ECI existed reject a symbol that has one. Switching the header off breaks UTF-8 text on the scanners that do support ECI, so the trade-off is real. Release 2026.9.2 added `EciMode` to control it, as the [ECI encoding guide](https://ironsoftware.com/barcode/csharp/how-to/eci-encoding/) describes.
Treat error messages the same way. A complete stack trace is the most useful input you can give an agent.
```text
TrackingScanner.ReadTrackingNumberAsync throws inside our Linux container. The
identical call succeeds on a Windows developer machine.
[PASTE FULL EXCEPTION AND STACK TRACE HERE]
Send the explorer subagent over the .csproj and the Dockerfile before changing
anything, and tell me which BarCode package we actually reference and what the
image is missing, quoting the line from each file that shows it.
Then give me the fix as a diff limited to those two files. Application code is
out of scope for this one.
```
Failures inside containers usually come from the platform package or a missing native dependency. Those fixes belong in the project file and Dockerfile, not in C#. Have Codex read [Run IronBarcode in Docker on Linux](https://ironsoftware.com/barcode/csharp/get-started/docker-linux/) for current deployment guidance before it changes anything.
## How do you turn one-off code into reusable, tested components?
When the round trip works, generalize it next. Agents handle this well because the pattern already exists in the file.
```text
Refactor ShippingLabelBarcode and TrackingScanner into a BarcodeService
registered with dependency injection. It should write any of Code 128, QR,
and DataMatrix, and read with options narrowed to the formats requested.
Reuse one BarcodeReaderOptions instance per format set rather than building
one per call. Add XML doc comments. Keep it under 80 lines.
```
The instruction to reuse options belongs in `AGENTS.md`. In a busy scanning service, building a fresh options object per request is allocation you pay on every scan.
Tests come next. A barcode either decodes back to the value you wrote or it does not, which keeps the assertions simple.
```text
This is a rebuild-and-rerun loop rather than a reasoning problem, so drop to
Luna with /model first. Cover BarcodeService with xUnit tests, then run them and
tell me the pass count.
Four behaviors need covering. A sample value survives a write and a read on
every format the service supports. EAN-13 rejects a value containing letters.
An image holding no barcode comes back empty instead of throwing. A path that
does not exist throws something a caller can read.
Never assert on image bytes. Decoded value and format are the only outputs
worth pinning.
```
Avoiding byte comparisons from the outset prevents unreliable tests. Encoders may produce slightly different image bytes across versions and platforms, even if the barcode remains unchanged. Instead, test the decoded value and format.
Codex is also useful for reading the documentation itself. When you name an unfamiliar class, it locates the relevant part of the [API reference](https://ironsoftware.com/barcode/csharp/object-reference/api/) rather than leaving you to scroll through the full page.
```text
$ironbarcode Read the IronBarcode API reference for BarcodeReaderOptions and
list every option that affects reading speed or accuracy, then show which ones
this project already sets.
```
## Which prompt pattern fits which task?
Every prompt above names something concrete and asks for something verifiable in return.
| Task | Name in the prompt | Ask back |
|---|---|---|
| Package | `BarCode`, the version, nothing else | The `PackageReference` line |
| License key | `IRONBARCODE_LICENSE_KEY`, startup path | `License.IsLicensed` true |
| Writer and reader | Symbology, both paths, image size | Two files that compile |
| Migration | Legacy file, signatures to keep | A mapping table, before code |
| Failed scans | Image folder, reader options only | Read count before and after |
| False positives | `RemoveFalsePositive`, `ConfidenceThreshold` | The page it cited |
| Container failure | Stack trace, platform, two files | A diff, `.csproj` and Dockerfile |
| Refactor | Formats, DI shape, line budget | One options instance per format |
| Tests | Four behaviors, no byte asserts | The pass count |
## How do you reuse these prompts on the next project?
Each pattern moves to a new project with only the file names changed, which is why the rules belong in version control and not in a chat history.
To measure a session rather than trust it, the [AI coding assistants and agents guide](https://ironsoftware.com/barcode/csharp/ai-agents/ai/) hands one task to an agent and scores what comes back.
---
## Troubleshooting
- [Apply a License Key in IronBarcode](https://ironsoftware.com/barcode/csharp/troubleshooting/apply-a-license-key-in-ironbarcode/) when a diff looks right and the run still throws.
- [Barcode Not Recognized](https://ironsoftware.com/barcode/csharp/troubleshooting/barcode-not-recognized/) when the scanner Codex wrote returns nothing for images that should read.
- [Avoiding False Positives in Barcode Scanning](https://ironsoftware.com/barcode/csharp/troubleshooting/false-positives/) when values come back from photos holding no barcode at all.
- [Run IronBarcode in Docker on Linux](https://ironsoftware.com/barcode/csharp/get-started/docker-linux/) when the same code passes on Windows and fails in the container.
---
## Questions?
If you have any questions, reach out to [support@ironsoftware.com](mailto:support@ironsoftware.com)
IronBarcode provides two encoding enums whose casing differs, BarcodeEncoding.Databar and BarcodeWriterEncoding.DataBar, and a model working from memory mixes them up. A compiler catches that immediately, which is the argument for an agent that builds the code it writes. ChatGPT Codex works inside the repository, so it runs dotnet build and reads the error itself. The quieter faults cost more, such as a reader left to search every symbology when every label in the batch is Code 128.
That difference decides which tier to run. Codex spans the GPT-5.6 family, and /model switches between Sol, Terra, and Luna inside an interactive session. A rebuild-and-rescan loop over a fixed test set is cheap work that Luna handles at 5 credits per million input tokens, against 100 for Sol. Terra is the middle tier at 50 credits per million input and 300 per million output, and it is a reasonable default once a project holds more than a test set. Reserve Sol, the flagship of the family, for harder diagnostic work, such as a batch of warehouse photos that fails to decode without reporting a cause.
IronBarcode reads and writes both 1D and 2D symbols through one commercial .NET API. Codex handles some of this work better than others. It is good at pinning the package version, building a label writer and a scanner, reading barcodes out of PDFs, correcting images a reader rejects, and migrating off another barcode library, and each of those starts with a prompt.
Quickstart
Install with NuGet
PM > Install-Package BarCode
Install-Package BarCode
Install IronBarcode by running the command above in the NuGet Package Manager Console, or search for the package in the NuGet Package Manager.
Start Codex from a clean working tree in a console project. Clearly state the desired outcome, any constraints, and the information you want reported.
$ironbarcode Add the BarCode package, then update Program.cs to read a scannedmulti-page TIFF and report every barcode it finds, page by page. Each line of outputshould give the page number, the decoded value and the format. Use the licensekey from IRONBARCODE_LICENSE_KEY.Constraints: Use only documented IronBarcode APIs. Do not modify or use anyother packages.Build the project, resolve any errors, and provide the diff alongside theoutput from a sample file.
$ironbarcode Add the BarCode package, then update Program.cs to read a scanned
multi-page TIFF and report every barcode it finds, page by page. Each line of output
should give the page number, the decoded value and the format. Use the license
key from IRONBARCODE_LICENSE_KEY.
Constraints: Use only documented IronBarcode APIs. Do not modify or use any
other packages.
Build the project, resolve any errors, and provide the diff alongside the
output from a sample file.
Text
A correct solution is short, because BarcodeReader.Read walks the frames of a multi-page TIFF or animated GIF on its own, without manual frame separation. Setting ExpectMultipleBarcodes helps when a single frame holds several symbols, but the reader reaches every frame either way. The prompt is longer than the resulting code, and requesting the diff up front allows you to review the actual changes rather than a description. Each result carries a 1-based PageNumber, which supplies the page-by-page output the prompt asks for, and the multi-page GIF and TIFF guide covers the read.
Commit an AGENTS.md file specifying IronBarcode as the project's barcode library
Start Codex from a clean working tree and include the symbology, files, and expected read-back in the prompt
Allow Codex to edit files and run dotnet build, then review the diff before accepting any changes
Complete the round trip and verify each IronBarcode API name against the API reference
How does Codex fit into a .NET barcode project?
Within the permissions you give it, Codex reads and writes files, runs shell commands, and shows what it did. OpenAI ships the same agent through several entry points that share your account and history. The Codex CLI and IDE extension documentation explain how they differ.
Surface
Where it runs
Reach for it when
CLI
Terminal
The agent should sit beside dotnet build
IDE extension
VS Code, JetBrains, Xcode
You want the diff and the barcode image side by side
Desktop app
macOS, Windows
A longer task, out of the terminal
Cloud
Browser
Delegating, and collecting the diff later
One AGENTS.md covers all four, because it is committed to the repository rather than attached to a surface.
To install the CLI, run npm install -g @openai/codex or, on macOS, brew install --cask codex. For macOS and Linux, a standalone installer is available that does not require Node.js: curl -fsSL https://chatgpt.com/codex/install.sh | sh. The Codex CLI repository contains the source code and release notes.
Please note: Include the @openai/ scope when installing. The npm package named codex is an unrelated static-site generator, first published in 2011 and last updated in 2012. IronBarcode has the opposite trap, because its NuGet package is BarCode, not IronBarcode. Exact package names matter when an agent is the one typing the command.
Codex does not reliably know IronBarcode's current API. It works from its training data and whatever documentation you give it, and calling a method that a later release removed is a common failure with third-party libraries. OpenAI builds Codex to run commands and check its output, yet still advises reviewing the work before release. The parent guide lists the documentation to hand any of these tools up front. Swap the context file name and the same setup carries to Claude Code, GitHub Copilot, Cursor, or Google Antigravity.
The tier changes the shape of the code as well as the bill. One prompt run on two tiers comes back structured two different ways, both defensible. Barcode encoding has to be the opposite, because one value goes in and one symbol comes out that every scanner reads identically. So state the symbology, the size, and the pass condition, and let the rest vary.
Four things follow from that, and they all argue for a maintained library over an agent-built one:
Validation runs on both sides: an invalid value is refused at write time with a named exception such as IronBarCodeFormatOnlyAcceptsNumericValuesEncodingException, while ConfidenceThreshold and RemoveFalsePositive throw out unreliable decodes on the way back.
Real scans are the hard part: phone photos, tilted labels, and multipage PDFs need crop regions, speed presets, and image filters, all three of which sit on BarcodeReaderOptions.
One API covers the formats: Code 128, GS1-128, EAN, UPC, QR, DataMatrix, PDF417, Aztec, MaxiCode, and more share the same read and write calls, listed in full under Supported Barcode Formats.
Someone is patching it: popular free barcode projects go unmaintained while a commercial library has someone accountable, with fixes published on a security CVE page.
A homemade encoder will happily draw a value its format cannot legally hold, and any library decodes a clean generated image. Verify is what separates the two, decoding a generated image and comparing it with the value you wrote.
What makes an IronBarcode prompt effective?
Specific answers to six questions. Vague prompts yield generic code aimed at a library that does not exist, and specific prompts yield code you can review in half a minute.
Component
Weak
Strong
Framework
Make a barcode
C#, .NET 9
Location
Unstated
Services/LabelService.cs
Version
Unstated
The BarCode version in the .csproj
Symbology
A barcode
Code 128, the tracking number
Output
A nice barcode
PNG 400x120, value below, reads back identically
Limits
None
No new packages. Async reads. Ask if unsure.
Language models tend to produce an answer rather than concede uncertainty. Tell the agent that reporting uncertainty is an acceptable outcome, and it invents fewer APIs. Give it explicit permission to stop instead of guessing.
Tips: Use the strong column as a checklist. With six answers in one prompt, most invented APIs never appear.
A committed AGENTS.md pays off across the project, because Codex loads it as standing instructions at the start of every session. The root file is read first and nested files after, and the nearest file wins, so a second AGENTS.md inside a barcode folder tightens the rules for that folder without touching the rest of the repository. /init generates a starter file if you have none.
Reference IronBarcode's machine-readable documentation in the file. The llms.txt file lists each documentation page with a summary, and skill.md carries the per-platform packages, the licensing rules, worked recipes, and the exception names to expect when something fails.
Codex scans .agents/skills in every directory from your working directory up to the repository root, so skill.md has a home of its own as .agents/skills/ironbarcode/SKILL.md. Codex matches a task against the frontmatter description, and you can force it with $ironbarcode when you want the recipes in context from the first turn. The same folder works in Antigravity, which reads that path too. Ask for both, and for the nested file:
Run /init if AGENTS.md does not exist yet. Then add a Barcodes section to theroot AGENTS.md: IronBarcode (NuGet package BarCode, namespace IronBarCode) isthe only barcode library in this repository, and no competing package may beadded. https://ironsoftware.com/barcode/csharp/llms.txt gets read before anybarcode code gets written, and a member that does not appear there does not getcalled. https://ironsoftware.com/barcode/csharp/skill.md belongs in.agents/skills/ironbarcode/SKILL.md. The license key is read from theIRONBARCODE_LICENSE_KEY environment variable and is never inlined.Then add a second AGENTS.md under Services/ that narrows this to the readeroptions this folder relies on, so the nested file wins there. Show me both filesas a diff before you commit anything.
Run /init if AGENTS.md does not exist yet. Then add a Barcodes section to the
root AGENTS.md: IronBarcode (NuGet package BarCode, namespace IronBarCode) is
the only barcode library in this repository, and no competing package may be
added. https://ironsoftware.com/barcode/csharp/llms.txt gets read before any
barcode code gets written, and a member that does not appear there does not get
called. https://ironsoftware.com/barcode/csharp/skill.md belongs in
.agents/skills/ironbarcode/SKILL.md. The license key is read from the
IRONBARCODE_LICENSE_KEY environment variable and is never inlined.
Then add a second AGENTS.md under Services/ that narrows this to the reader
options this folder relies on, so the nested file wins there. Show me both files
as a diff before you commit anything.
Text
How do you ask Codex to add IronBarcode and write a first barcode?
Let the agent handle setup first. Version and package-name mistakes start there.
This project needs IronBarcode. Pull in the BarCode package, then show me theresulting PackageReference line from the .csproj and tell me which version wasinstalled. Do not change any other package references.
This project needs IronBarcode. Pull in the BarCode package, then show me the
resulting PackageReference line from the .csproj and tell me which version was
installed. Do not change any other package references.
Text
Expect a one-line diff and the version it installed. That number is worth citing in later prompts, and it exposes an agent that added a different package with barcode in its name. To pin a specific release instead, consult the IronBarcode changelog.
IronBarcode has no watermark mode. Past the development grace period, an unlicensed call fails outright with LicensingException. Set the key at startup, ahead of every other IronBarcode call, and let Codex add it.
Wire up licensing. Nothing else in IronBarcode may run ahead of it, so it goeswherever this project does its startup work, pulling the value out ofIRONBARCODE_LICENSE_KEY rather than carrying a key in source.Prove it took by checking IronBarCode.License.IsLicensed, and tell me which fileyou put the call in.
Wire up licensing. Nothing else in IronBarcode may run ahead of it, so it goes
wherever this project does its startup work, pulling the value out of
IRONBARCODE_LICENSE_KEY rather than carrying a key in source.
Prove it took by checking IronBarCode.License.IsLicensed, and tell me which file
you put the call in.
Text
The IronBarcode License Keys documentation covers trial keys and all other licensing options, including Web.config and appsettings.json.
Next, build a label service and a scanner. In real systems, barcodes are created in one place and read somewhere else.
Two files, one job. Shipping labels go out as Code 128 PNGs at 400 by 120with the tracking number printed under the bars, and something on the receivingend has to turn that image back into the tracking number.Put the writer in Services/ShippingLabelBarcode.cs and the reader inServices/TrackingScanner.cs. The read is async and returns null rather thanthrowing when the image holds nothing.Compile, clear the errors, and report back with the changed files and whicheverBarCode version the restore resolved to.
Two files, one job. Shipping labels go out as Code 128 PNGs at 400 by 120
with the tracking number printed under the bars, and something on the receiving
end has to turn that image back into the tracking number.
Put the writer in Services/ShippingLabelBarcode.cs and the reader in
Services/TrackingScanner.cs. The read is async and returns null rather than
throwing when the image holds nothing.
Compile, clear the errors, and report back with the changed files and whichever
BarCode version the restore resolved to.
Text
Check every member in the diff against the API reference before you accept it. A correct writer builds on BarcodeWriter.CreateBarcode, ResizeTo, AddBarcodeValueTextBelowBarcode, SetMargins, and ToPngBinaryData, and a correct reader on BarcodeReaderOptions and BarcodeReader.ReadAsync, with ExpectBarcodeTypes naming the symbology so the reader stops searching every format. For images from cameras or scanners rather than this service, the image correction guide explains the filters that rescue weak scans.
How do you migrate an existing barcode implementation to IronBarcode?
Migration work is repetitive and mechanical, which is what agents do well. Point the prompt at the actual code instead of summarizing it.
Hand this to the explorer agent, because nothing here should be written yet.Labels/LegacyBarcodeService.cs currently writes and reads barcodes with anotherlibrary.1. List every symbology it writes and reads, with the options it sets (size, margins, text, check digits, error correction).2. Map each call to its IronBarcode equivalent, citing the documentation page.3. Do not write any code yet. Wait for my approval on the plan.
Hand this to the explorer agent, because nothing here should be written yet.
Labels/LegacyBarcodeService.cs currently writes and reads barcodes with another
library.
1. List every symbology it writes and reads, with the options it sets
(size, margins, text, check digits, error correction).
2. Map each call to its IronBarcode equivalent, citing the documentation page.
3. Do not write any code yet. Wait for my approval on the plan.
Text
A 400-line implementation calls for a line-by-line review, while an error in a mapping table costs a single correction and no discarded code.
Please note: Planning first adds one exchange, and spares you from reviewing a diff you never approved.
Once you approve the plan, the next prompt stays tightly scoped.
Put the worker agent on the approved plan. Rewrite LegacyBarcodeService.cs touse IronBarcode, keeping the existing public method signatures so callers donot change.Before removing the old library, generate every symbology the servicesupports with both implementations and confirm IronBarcode reads back thesame values. Leave the old library in Git history only. Build and report the diff.
Put the worker agent on the approved plan. Rewrite LegacyBarcodeService.cs to
use IronBarcode, keeping the existing public method signatures so callers do
not change.
Before removing the old library, generate every symbology the service
supports with both implementations and confirm IronBarcode reads back the
same values. Leave the old library in Git history only. Build and report the diff.
Text
State in the prompt that the public method signatures must not change. Without that instruction, an agent will often redesign how callers use the service, which turns a migration into a refactor. Generating every symbology with both implementations and comparing the decoded values gives you a regression test, and it costs one extra build-and-run cycle.
How do you fix scans that do not read through prompts?
A failed read is a visual problem, and the agent has no view of the camera. Your prompt must describe the problem, or better, include the images.
TrackingScanner finds nothing in TestData/warehouse/, yet a warehouse operatorcan point a handheld at the same printed label and get a read. The photos areshot at an angle and a few are soft. I have attached one of the failing photoswith `codex -i`, so look at it rather than reasoning from the file names.Read TrackingScanner.cs and a sample of the images. Explain the likely causebefore changing anything, then adjust BarcodeReaderOptions only (speed, croparea, image filters). Do not change ShippingLabelBarcode.cs. Report how manyimages read before and after.
TrackingScanner finds nothing in TestData/warehouse/, yet a warehouse operator
can point a handheld at the same printed label and get a read. The photos are
shot at an angle and a few are soft. I have attached one of the failing photos
with `codex -i`, so look at it rather than reasoning from the file names.
Read TrackingScanner.cs and a sample of the images. Explain the likely cause
before changing anything, then adjust BarcodeReaderOptions only (speed, crop
area, image filters). Do not change ShippingLabelBarcode.cs. Report how many
images read before and after.
Text
Stating the symptom and naming the one file to edit keeps the fix contained. A before-and-after count replaces a vague sense of improvement with a number. The fix is usually one of three: Speed raised to Detailed, a CropArea drawn round the label, or a single image filter chosen for the actual defect. Stacking filters makes accuracy worse, not better. Details are on the reading speed and crop region pages.
False positives are the reverse problem. Handle them the same way.
ScanService occasionally returns a value from product photos that contain nobarcode. Set RemoveFalsePositive and a ConfidenceThreshold on the reader options,then link me to the documentation page you used.
ScanService occasionally returns a value from product photos that contain no
barcode. Set RemoveFalsePositive and a ConfidenceThreshold on the reader options,
then link me to the documentation page you used.
Text
The documentation link doubles as a check. An agent that cannot cite a real page for the API it chose has warned you before the build does. Reader options are easy to invent, so keep the false positives guide nearby.
How do you debug a barcode failure end to end?
Each earlier prompt covers one task. Codex does more when you hand it a symptom and let it inspect, diagnose, fix, and test on its own.
Switch to Sol with /model before you start, because this one has resisted thecheaper tiers. DataMatrix labels with non-English product names are refused bysome of our older handheld scanners, while labels with plain ASCII names readfine on the same devices, and every label reads correctly with IronBarcodeitself.Investigate:1. Read LabelService.cs and find how the DataMatrix codes are created.2. Identify why the non-English labels fail on those scanners only.3. Explain the cause before changing anything.4. Then propose the minimal fix, and what it costs, before applying it.
Switch to Sol with /model before you start, because this one has resisted the
cheaper tiers. DataMatrix labels with non-English product names are refused by
some of our older handheld scanners, while labels with plain ASCII names read
fine on the same devices, and every label reads correctly with IronBarcode
itself.
Investigate:
1. Read LabelService.cs and find how the DataMatrix codes are created.
2. Identify why the non-English labels fail on those scanners only.
3. Explain the cause before changing anything.
4. Then propose the minimal fix, and what it costs, before applying it.
Text
Asking for the cause first gives you a diagnosis to judge, rather than an edit to decode afterward. Here the likely cause is the UTF-8 ECI header. IronBarcode writes that header only when the text carries non-ASCII characters, and scanners built before ECI existed reject a symbol that has one. Switching the header off breaks UTF-8 text on the scanners that do support ECI, so the trade-off is real. Release 2026.9.2 added EciMode to control it, as the ECI encoding guide describes.
Treat error messages the same way. A complete stack trace is the most useful input you can give an agent.
TrackingScanner.ReadTrackingNumberAsync throws inside our Linux container. Theidentical call succeeds on a Windows developer machine.[PASTE FULL EXCEPTION AND STACK TRACE HERE]Send the explorer subagent over the .csproj and the Dockerfile before changinganything, and tell me which BarCode package we actually reference and what theimage is missing, quoting the line from each file that shows it.Then give me the fix as a diff limited to those two files. Application code isout of scope for this one.
TrackingScanner.ReadTrackingNumberAsync throws inside our Linux container. The
identical call succeeds on a Windows developer machine.
[PASTE FULL EXCEPTION AND STACK TRACE HERE]
Send the explorer subagent over the .csproj and the Dockerfile before changing
anything, and tell me which BarCode package we actually reference and what the
image is missing, quoting the line from each file that shows it.
Then give me the fix as a diff limited to those two files. Application code is
out of scope for this one.
Text
Failures inside containers usually come from the platform package or a missing native dependency. Those fixes belong in the project file and Dockerfile, not in C#. Have Codex read Run IronBarcode in Docker on Linux for current deployment guidance before it changes anything.
How do you turn one-off code into reusable, tested components?
When the round trip works, generalize it next. Agents handle this well because the pattern already exists in the file.
Refactor ShippingLabelBarcode and TrackingScanner into a BarcodeServiceregistered with dependency injection. It should write any of Code 128, QR,and DataMatrix, and read with options narrowed to the formats requested.Reuse one BarcodeReaderOptions instance per format set rather than buildingone per call. Add XML doc comments. Keep it under 80 lines.
Refactor ShippingLabelBarcode and TrackingScanner into a BarcodeService
registered with dependency injection. It should write any of Code 128, QR,
and DataMatrix, and read with options narrowed to the formats requested.
Reuse one BarcodeReaderOptions instance per format set rather than building
one per call. Add XML doc comments. Keep it under 80 lines.
Text
The instruction to reuse options belongs in AGENTS.md. In a busy scanning service, building a fresh options object per request is allocation you pay on every scan.
Tests come next. A barcode either decodes back to the value you wrote or it does not, which keeps the assertions simple.
This is a rebuild-and-rerun loop rather than a reasoning problem, so drop toLuna with /model first. Cover BarcodeService with xUnit tests, then run them andtell me the pass count.Four behaviors need covering. A sample value survives a write and a read onevery format the service supports. EAN-13 rejects a value containing letters.An image holding no barcode comes back empty instead of throwing. A path thatdoes not exist throws something a caller can read.Never assert on image bytes. Decoded value and format are the only outputsworth pinning.
This is a rebuild-and-rerun loop rather than a reasoning problem, so drop to
Luna with /model first. Cover BarcodeService with xUnit tests, then run them and
tell me the pass count.
Four behaviors need covering. A sample value survives a write and a read on
every format the service supports. EAN-13 rejects a value containing letters.
An image holding no barcode comes back empty instead of throwing. A path that
does not exist throws something a caller can read.
Never assert on image bytes. Decoded value and format are the only outputs
worth pinning.
Text
Avoiding byte comparisons from the outset prevents unreliable tests. Encoders may produce slightly different image bytes across versions and platforms, even if the barcode remains unchanged. Instead, test the decoded value and format.
Codex is also useful for reading the documentation itself. When you name an unfamiliar class, it locates the relevant part of the API reference rather than leaving you to scroll through the full page.
$ironbarcode Read the IronBarcode API reference for BarcodeReaderOptions andlist every option that affects reading speed or accuracy, then show which onesthis project already sets.
$ironbarcode Read the IronBarcode API reference for BarcodeReaderOptions and
list every option that affects reading speed or accuracy, then show which ones
this project already sets.
Text
Which prompt pattern fits which task?
Every prompt above names something concrete and asks for something verifiable in return.
Task
Name in the prompt
Ask back
Package
BarCode, the version, nothing else
The PackageReference line
License key
IRONBARCODE_LICENSE_KEY, startup path
License.IsLicensed true
Writer and reader
Symbology, both paths, image size
Two files that compile
Migration
Legacy file, signatures to keep
A mapping table, before code
Failed scans
Image folder, reader options only
Read count before and after
False positives
RemoveFalsePositive, ConfidenceThreshold
The page it cited
Container failure
Stack trace, platform, two files
A diff, .csproj and Dockerfile
Refactor
Formats, DI shape, line budget
One options instance per format
Tests
Four behaviors, no byte asserts
The pass count
How do you reuse these prompts on the next project?
Each pattern moves to a new project with only the file names changed, which is why the rules belong in version control and not in a chat history.
Curtis Chau holds a Bachelor’s degree in Computer Science (Carleton University) and specializes in front-end development with expertise in Node.js, TypeScript, JavaScript, and React. Passionate about crafting intuitive and aesthetically pleasing user interfaces, Curtis enjoys working with modern frameworks and creating well-structured, visually appealing manuals.