can1357/oh-my-pi · error · Error
Operation ${operationNumber} did not match ${path}: your lin
Error message
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} What it means
The pattern's individual lines each match somewhere in the file, but the matched locations are not consecutive, so no single ordered region satisfies the whole pattern. The library detects this specific failure (via `nonConsecutiveGuidance`) and throws an error that includes a copy-ready corrected pattern with proper `...` gaps and guidance about the span the rewrite will replace.
Source
Thrown at packages/coding-agent/src/edit/sloppy.ts:2500
// Sibling-claim disambiguation: an ambiguous op whose extra candidates are
// already claimed by other operations' planned edits resolves to the free
// one. Only ever narrows; all-excluded keeps the ambiguity diagnosis.
if (exclusions !== undefined && candidates.length > 1) {
const free = candidates.filter(
candidate => !exclusions.some(claim => candidate.matchStart < claim.end && claim.start < candidate.matchEnd),
);
if (free.length > 0) candidates = free;
}
if (operation.all && candidates.length > 0) return candidates;
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),View on GitHub (pinned to 9690622007)
Solutions
- Use the copy-ready corrected operation included in the error — it inserts `...` between the non-adjacent lines.
- Re-read the region and rebuild the pattern from the actual consecutive lines.
- If the skipped lines are fine to leave, keep them under a `...` gap and note the REWRITE/inline replacement covers the whole span, so re-emit kept lines explicitly.
Example fix
// before const pattern = "const a = 1;\nconst c = 3;"; // b exists between them // after const pattern = "const a = 1;\n...\nconst c = 3;";
Defensive patterns
Strategy: try-catch
Validate before calling
// Verify the pattern lines are consecutive in the file before applying:
const idxs = patternLines.filter(l => l.trim()).map(l => {
const i = content.split("\n").findIndex(f => f === l);
return i;
});
const consecutive = idxs.every((v, k) => k === 0 || v === idxs[k - 1] + 1);
if (!consecutive) throw new Error("pattern lines are not consecutive; add ... between them"); Try / catch
try {
await applySloppyEdit({ pattern });
} catch (err) {
if (err instanceof Error && err.message.includes("not consecutive")) {
// use the copy-ready corrected operation printed in the error message
const corrected = extractCorrectedPattern(err.message);
return applySloppyEdit({ pattern: corrected });
}
throw err;
} Prevention
- Reconstruct patterns from the current file content, never from memory.
- Insert `...` whenever you know or suspect lines are separated in the file.
- Use the copy-ready corrected pattern the error emits — it is designed to be retried directly.
When it happens
Trigger: Writing a multi-line pattern where lines appear in the file but with other code between them (order preserved but not adjacent), e.g. assuming two statements are neighbors when an intervening line exists. Detected when `collectCandidates` finds zero matches but individual line searches succeed at separated locations.
Common situations: Reconstructing code from memory instead of the actual file; lines separated by a blank line, comment, or an edited statement; copying lines from different parts of a function into one pattern.
Related errors
- Operation ${operationNumber} pattern is too broad; add anoth
- Operation ${operationNumber} adds or removes whole lines but
- ${operation.all ? `Operation ${operationNumber} ${OPENER}* f
- Operation ${operationNumber} is ambiguous: ${candidates.leng
- Operation ${operationNumber} has no visible current text.
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/85d3f7f3d4db6298.
Report an issue: GitHub.