editkit / docs

Failure handling

Every ApplyResult is either ok:true (with before/after) or ok:false (with reason + message). Pipe messages straight back into a retry prompt.

Every ApplyResult is either:

{ ok: true, before, after, edit, path }
// or
{ ok: false, reason, message, edit, path }

The message strings are written to be model-readable — pipe them straight into the next prompt. The reason codes are stable identifiers you can branch on in code.

Reason codes

reasonwhat it means
search-not-foundThe SEARCH block doesn't appear in the file (even with fuzzing).
ambiguous-matchThe SEARCH block appears more than once.
hunk-context-mismatchA unified-diff hunk's context lines don't appear in the file.
missing-originalThe file doesn't exist and allowCreate is false.
invalid-formatThe block can't be parsed.

Retry pattern

const results = await applyEdits(text, fileReader);
const failures = results.filter((r) => !r.ok);

if (failures.length) {
  const errorBlock = failures
    .map((f) => `${f.path}: ${f.message}`)
    .join("\n");

  // Re-render the affected files' current contents — the model needs both the
  // failure message AND fresh source to re-quote from.
  const affectedFiles = await Promise.all(
    [...new Set(failures.map((f) => f.path))].map(async (p) => {
      const content = await readFile(p, "utf8");
      return `### ${p}\n\`\`\`\n${content}\n\`\`\``;
    }),
  );

  const retryPrompt = `Your previous edit failed:\n${errorBlock}\n\nHere is the current state of the affected files:\n\n${affectedFiles.join("\n\n")}\n\nTry again.`;

  // ... call the model with retryPrompt
}

The failure message names the path and the problem but does not echo the SEARCH block that failed. That's intentional — re-rendering the file is what gives the model fresh source to re-quote from.

Bail after one retry

If the model can't recover from its own structured failure message, two more rounds rarely help. The aider design treats the failure message as a single high-signal correction. After one retry, surface the failure to the human (or to your test runner) rather than burning tokens.

See the test-fix loop recipe for the full pattern.

On this page