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

  1. Read the numbered preview embedded in the error — it shows the closest region without re-reading the file — and correct the pattern from it.
  2. Use the copy-ready corrected operation included in the error message.
  3. Re-read the current file region and rebuild the pattern byte-for-byte.
  4. 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

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


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/96ca8602f540a7f4. Report an issue: GitHub.