can1357/oh-my-pi · error · Error
${operation.all ? `Operation ${operationNumber} ${OPENER}* f
Error message
${operation.all ? `Operation ${operationNumber} ${OPENER}* found 0 matches in ${path}. ${guidance.reason}` : `Operation ${operationNumber} did not match ${path}. ${guidance.reason}`}
Current file content near the closest match (no re-read needed):
${numberedPreview(content, guidance.previewOffset)}
Copy-ready corrected operation:
${operationPayload(operation, operation.all ? "*" : "", guidance.correctedPattern)} What it means
The generic no-match failure: after all fallback strategies the pattern did not match anywhere in the file. The library throws with a diagnostic reason (`guidance.reason`), a numbered preview of the file content nearest the closest match (so no re-read is needed), and a copy-ready corrected operation pattern.
Source
Thrown at packages/coding-agent/src/edit/sloppy.ts:2510
if (candidates.length === 1) return [candidates[0]];
if (candidates.length === 0) {
const separated = nonConsecutiveGuidance(content, operation);
if (separated) {
const replacementGuidance =
operation.rewrite.kind === "explicit"
? `The REWRITE then replaces the whole span lines ${separated.locations[0]}-${separated.locations.at(-1)}, including the skipped lines — re-emit kept gaps with ${GAP}.`
: `The inline replacements then target the whole span lines ${separated.locations[0]}-${separated.locations.at(-1)}, including skipped lines — re-emit kept gaps with ${GAP}.`;
throw new Error(
[
`Operation ${operationNumber} did not match ${path}: your lines match individually at lines ${separated.locations.join(", ")} but are not consecutive.`,
"Copy-ready corrected operation:",
operationPayload(operation, operation.all ? "*" : "", separated.correctedPattern),
replacementGuidance,
].join("\n"),
);
}
const guidance = noMatchGuidance(content, normalized, pattern, operation);
throw new Error(
[
operation.all
? `Operation ${operationNumber} ${OPENER}* found 0 matches in ${path}. ${guidance.reason}`
: `Operation ${operationNumber} did not match ${path}. ${guidance.reason}`,
"Current file content near the closest match (no re-read needed):",
numberedPreview(content, guidance.previewOffset),
"Copy-ready corrected operation:",
operationPayload(operation, operation.all ? "*" : "", guidance.correctedPattern),
...(guidance.additionRetry ? [guidance.additionRetry] : []),
].join("\n"),
);
}
// Outcome-equivalent ambiguity is no ambiguity: when applying the rewrite
// at every candidate yields the same file (deleting either of two identical
// adjacent copies, rewriting interchangeable spans), pick the first.
if (candidates.length <= 4 && operation.desiredState !== true) {
const rewriteOf = operation.rewrite;
const outcomes = new Set(View on GitHub (pinned to 9690622007)
Solutions
- Read the numbered preview embedded in the error — it shows the closest region without re-reading the file — and correct the pattern from it.
- Use the copy-ready corrected operation included in the error message.
- Re-read the current file region and rebuild the pattern byte-for-byte.
- Verify the edit targets the correct file path.
Example fix
// before const pattern = "const total = computeTotl(items);"; // typo // after const pattern = "const total = computeTotal(items);";
Defensive patterns
Strategy: try-catch
Validate before calling
// Confirm the primary anchor line exists in a freshly-read file before applying:
const content = await Bun.file(path).text();
if (!content.includes(primaryAnchorLine)) {
throw new Error(`anchor not found in ${path}; refresh pattern from the file`);
} Try / catch
try {
await applySloppyEdit({ path, pattern });
} catch (err) {
if (err instanceof Error && (err.message.includes("did not match") || err.message.includes("found 0 matches"))) {
// error embeds a numbered preview of the nearest region and a corrected
// pattern — re-read that region, rebuild, retry once
return rebuildPatternFromPreviewAndRetry(err.message);
}
throw err;
} Prevention
- Always re-read the file (or use the error's embedded preview) before retrying a no-match.
- Check for typos in identifiers and string literals in the pattern.
- Confirm the edit targets the correct file path.
- Assume the file may have changed since your last read; patterns must be rebuilt from current content.
When it happens
Trigger: Any sloppy edit operation whose pattern has zero matches after raw, punctuation-tolerant, and literal-fallback passes — wrong content, wrong indentation, stale file view, or a pattern referencing code that does not exist. With `operation.all` set, the message reads "found 0 matches" instead of "did not match".
Common situations: File was modified (by another tool, linter, or prior edit) since it was last read; typos in identifiers or string literals; wrong indentation depth; targeting a different file than the one containing the code; model/agent hallucinating the region content.
Related errors
- Operation ${operationNumber} adds or removes whole lines but
- Operation ${operationNumber} pattern is too broad; add anoth
- Operation ${operationNumber} did not match ${path}: your lin
- Operation ${operationNumber} is ambiguous: ${candidates.leng
- Failed to find expected lines in ${path}:\n${hunk.oldLines.j
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/96ca8602f540a7f4.
Report an issue: GitHub.