{"record":{"id":"85d3f7f3d4db6298","repo":"can1357/oh-my-pi","slug":"operation-operationnumber-did-not-match-path","errorCode":null,"errorMessage":"Operation ${operationNumber} did not match ${path}: your lines match individually at lines ${separated.locations.join(\", \")} but are not consecutive.\nCopy-ready corrected operation:\n${operationPayload(operation, operation.all ? \"*\" : \"\", separated.correctedPattern)}\n${replacementGuidance}","messagePattern":"Operation (.+?) did not match (.+?): your lines match individually at lines (.+?) but are not consecutive\\.\nCopy-ready corrected operation:\n(.+?)\n(.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/edit/sloppy.ts","lineNumber":2500,"sourceCode":"\t// Sibling-claim disambiguation: an ambiguous op whose extra candidates are\n\t// already claimed by other operations' planned edits resolves to the free\n\t// one. Only ever narrows; all-excluded keeps the ambiguity diagnosis.\n\tif (exclusions !== undefined && candidates.length > 1) {\n\t\tconst free = candidates.filter(\n\t\t\tcandidate => !exclusions.some(claim => candidate.matchStart < claim.end && claim.start < candidate.matchEnd),\n\t\t);\n\t\tif (free.length > 0) candidates = free;\n\t}\n\tif (operation.all && candidates.length > 0) return candidates;\n\tif (candidates.length === 1) return [candidates[0]];\n\tif (candidates.length === 0) {\n\t\tconst separated = nonConsecutiveGuidance(content, operation);\n\t\tif (separated) {\n\t\t\tconst replacementGuidance =\n\t\t\t\toperation.rewrite.kind === \"explicit\"\n\t\t\t\t\t? `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}.`\n\t\t\t\t\t: `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}.`;\n\t\t\tthrow new Error(\n\t\t\t\t[\n\t\t\t\t\t`Operation ${operationNumber} did not match ${path}: your lines match individually at lines ${separated.locations.join(\", \")} but are not consecutive.`,\n\t\t\t\t\t\"Copy-ready corrected operation:\",\n\t\t\t\t\toperationPayload(operation, operation.all ? \"*\" : \"\", separated.correctedPattern),\n\t\t\t\t\treplacementGuidance,\n\t\t\t\t].join(\"\\n\"),\n\t\t\t);\n\t\t}\n\t\tconst guidance = noMatchGuidance(content, normalized, pattern, operation);\n\t\tthrow new Error(\n\t\t\t[\n\t\t\t\toperation.all\n\t\t\t\t\t? `Operation ${operationNumber} ${OPENER}* found 0 matches in ${path}. ${guidance.reason}`\n\t\t\t\t\t: `Operation ${operationNumber} did not match ${path}. ${guidance.reason}`,\n\t\t\t\t\"Current file content near the closest match (no re-read needed):\",\n\t\t\t\tnumberedPreview(content, guidance.previewOffset),\n\t\t\t\t\"Copy-ready corrected operation:\",\n\t\t\t\toperationPayload(operation, operation.all ? \"*\" : \"\", guidance.correctedPattern),","sourceCodeStart":2482,"sourceCodeEnd":2518,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/edit/sloppy.ts#L2482-L2518","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nconst pattern = \"const a = 1;\\nconst c = 3;\"; // b exists between them\n// after\nconst pattern = \"const a = 1;\\n...\\nconst c = 3;\";","handlingStrategy":"try-catch","validationCode":"// Verify the pattern lines are consecutive in the file before applying:\nconst idxs = patternLines.filter(l => l.trim()).map(l => {\n  const i = content.split(\"\\n\").findIndex(f => f === l);\n  return i;\n});\nconst consecutive = idxs.every((v, k) => k === 0 || v === idxs[k - 1] + 1);\nif (!consecutive) throw new Error(\"pattern lines are not consecutive; add ... between them\");","typeGuard":null,"tryCatchPattern":"try {\n  await applySloppyEdit({ pattern });\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"not consecutive\")) {\n    // use the copy-ready corrected operation printed in the error message\n    const corrected = extractCorrectedPattern(err.message);\n    return applySloppyEdit({ pattern: corrected });\n  }\n  throw err;\n}","preventionTips":["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."],"tags":["edit-pattern","matching","non-consecutive-lines"],"backgroundTag":"edit-pattern-no-match","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}