All posts

From an error report to a reviewed fix

Dennis Zaiser, technical founder

Most production errors travel the same path. An alert fires, someone copies it into a ticket, adds what they can, and eventually someone else picks it up. With coding agents, every step after the alert can run without a person, except the one that should have one: deciding that the fix is right. Here is that path as a single story, from the moment an error tracker reports a new issue to the moment a reviewed change lands.

The error arrives

Say a release goes out on a Thursday and, an hour later, the checkout page starts throwing an error when a cart is emptied and then refreshed. Your error tracker groups the occurrences into a new issue and, like most error trackers, can send a webhook when that happens.

The triage workflow has a webhook trigger, which gives it an address of its own. The tracker posts each new issue to that address, and the call starts a run. Nothing reads back into the tracker, and nothing has to be set up on its side beyond the address. The run starts with the issue's title, its fingerprint, the stack trace and a link back.

The address is all the caller needs to know. The same kind of trigger works for anything that can send a web request: an uptime monitor, a support form, a deploy script.

Triage: has this been seen before?

The first node is an agent that reads the error and checks the error ledger: a dataset with columns you define, one row per error, holding its fingerprint, when it was first and last seen, how often it occurred and the item it belongs to.

A condition node then asks one question: is there an open item for this fingerprint? If yes, the run updates the row, adds the new occurrence to the existing item and ends as known. If no, it writes a new row and files an item on the triage board. The item is a bug, a record type with a severity, steps to reproduce and a summary of the trace.

This is what keeps a spike from becoming fifty tickets. The same error arriving fifty times in ten minutes makes one item, and one row with a count of fifty.

From the board to a fix

The triage board's columns are the bug's statuses: new, ready to fix, fixing, in review, done. A person, or a rule on severity, moves the checkout bug to ready to fix, and that column starts the fix workflow. Severity can steer more than order: a critical bug can go straight to ready to fix through a rule, while a minor one waits for a person to pick it during the week.

The engine picks it up when it is ready, meaning nothing blocks it and nothing it depends on is unfinished, in the order the roadmap sets and within how much may run at once. The run gets an isolated working copy of the repository on your machine or server, and the context step hands the agent the rules for the part of the code the trace points to.

The fix loop

The fix workflow starts with reproduction. The agent writes a failing test that triggers the same error, because a fix without a reproduction is a guess. That test is a required output: the node can't close without it.

Then comes a loop. The agent changes the code, and the checks run in the working copy: the new test, the existing suite, the type check, the lint. If they pass, the loop ends. If not, it runs again with the failures as input, until the checks pass or the loop reaches the limit you set, at which point the run waits for you with an account of what it tried. The agent's own summary never decides: the check results do.

A person approves

When the checks pass, the run reaches an approval node and stops. Waiting costs nothing, and the engine moves on to other ready work. In your inbox the approval shows the item, the original error, the reproducing test, the check results and the branch.

What you judge is narrow, which is why it is quick: does the test reproduce the reported error, and does the change fix it without changing anything else? The checks have already answered whether it builds and whether the suite passes. You read the diff in your repository, where the code lives. Then you approve it, send it back with a note, which sends the loop round again with your note as input, or cancel it. An agent the engine started never approves its own work.

The change lands, and the ledger remembers

After approval, the engine lands the change one at a time with your checks, or leaves the branch for your own review process, whichever the workflow says. The run ends as fixed, the item moves to done, and the ledger row points to the item and its fix. The history records who approved it and when.

If the same error returns after the next release, the triage run finds the row, sees that the item is done, and reopens it with the new occurrence instead of filing a fresh one. The regression arrives with its whole history attached: the first report, the reproducing test, the fix and who approved it.

Where ctxflows fits

Every piece of this story is a ctxflows feature. On the Workflows page: the webhook trigger, and the four node kinds the story uses, agent, condition, loop and approval. Datasets hold the error ledger, written by one run and read by the next. Boards define the triage board, with the bug record type's statuses as its columns and a column that starts the fix workflow.

Runs & actions is where the approval waits with its outputs, checks and branch, among everything else waiting on you. The Engine page covers the rest: isolated working copies, checks on your machine and changes landed one at a time. Your code never enters ctxflows; the run carries the error, the item and the results, and the diff stays in your repository.

Give your coding agents the context and the workflows

ctxflows is the context layer and the workflows for agent-built software.