{"record":{"id":"6c9382a393b7c42c","repo":"can1357/oh-my-pi","slug":"operation-operationnumber-adds-or-removes-whole","errorCode":null,"errorMessage":"Operation ${operationNumber} adds or removes whole lines but MATCH did not match byte-for-byte. Re-read the region and copy its exact indentation.","messagePattern":"Operation (.+?) adds or removes whole lines but MATCH did not match byte-for-byte\\. Re-read the region and copy its exact indentation\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/edit/sloppy.ts","lineNumber":2418,"sourceCode":"\t\t);\n\t});\n}\n\nfunction locate(\n\tcontent: string,\n\tpattern: ParsedPattern,\n\toperation: Operation,\n\toperationNumber: number,\n\tpath: string,\n\texclusions?: ReadonlyArray<{ start: number; end: number }>,\n): Candidate[] {\n\tconst normalized = normalizeText(content);\n\tconst raw = collectCandidates(content, normalized, pattern, \"raw\");\n\tif (raw.overflow) {\n\t\tthrow new Error(`Operation ${operationNumber} pattern is too broad; add another distinctive ${GAP} fragment.`);\n\t}\n\tif (raw.candidates.length === 0 && hasMarkerLines(operation.sourcePatternText)) {\n\t\tthrow new Error(\n\t\t\t`Operation ${operationNumber} adds or removes whole lines but MATCH did not match byte-for-byte. Re-read the region and copy its exact indentation.`,\n\t\t);\n\t}\n\tif (raw.candidates.length === 0 && pattern.literalFallback) {\n\t\tconst exact = exactOccurrences(normalized.text, pattern.literalFallback.normalized);\n\t\tif (exact.length > 0 && (operation.all || exact.length === 1)) {\n\t\t\tconst fallbackCandidates = exact.map(occurrence => {\n\t\t\t\tconst matchStart = sourceStart(normalized, occurrence.start, 0);\n\t\t\t\tconst matchEnd = sourceEnd(normalized, occurrence.end, content.length);\n\t\t\t\tconst fallbackStart = occurrence.start + pattern.literalFallback!.selectionStart;\n\t\t\t\tconst fallbackEnd = occurrence.start + pattern.literalFallback!.selectionEnd;\n\t\t\t\tconst start =\n\t\t\t\t\tpattern.literalFallback!.selectionStart === pattern.literalFallback!.normalized.length\n\t\t\t\t\t\t? matchEnd\n\t\t\t\t\t\t: sourceStart(normalized, fallbackStart, matchEnd);\n\t\t\t\tconst end =\n\t\t\t\t\tpattern.literalFallback!.selectionEnd === pattern.literalFallback!.normalized.length\n\t\t\t\t\t\t? matchEnd","sourceCodeStart":2400,"sourceCodeEnd":2436,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/edit/sloppy.ts#L2400-L2436","documentation":"The pattern contains whole-line markers (gap-based line matching) so it is expected to match the file byte-for-byte at the line level, but raw candidate collection found zero matches. The library throws this with explicit guidance: re-read the target region and copy its exact indentation, because the lines as written do not appear verbatim in the file.","triggerScenarios":"An operation that adds/removes whole lines (pattern built from marker lines via `hasMarkerLines`) where none of the literal lines match the file exactly — typically due to wrong indentation, tabs vs spaces, or stale content after the file changed.","commonSituations":"Working from an outdated file view (file edited since last read); mixing tab-indented file content with space-indented pattern (or vice versa); off-by-one indentation when copying nested blocks; CRLF vs LF in hand-crafted patterns.","solutions":["Re-read the target region and copy the lines byte-for-byte, preserving exact leading whitespace.","Check indentation characters: the file may use tabs where your pattern uses spaces (or different depth).","If only part of the region matters, convert the pattern to partial-line matching with `...` gaps instead of whole-line markers."],"exampleFix":"// before (pattern, file uses 2-space indent)\nconst pattern = \"    return sum(a, b);\";\n// after\nconst pattern = \"  return sum(a, b);\";","handlingStrategy":"validation","validationCode":"// Verify each pattern line exists byte-for-byte in the current file content\n// (after refreshing the file view) before applying.\nconst missing = patternLines.filter(l => !content.includes(l));\nif (missing.length > 0) {\n  throw new Error(`lines not found verbatim: ${JSON.stringify(missing)}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await applySloppyEdit({ pattern });\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"byte-for-byte\")) {\n    // re-read the region, copy exact indentation (tabs vs spaces), retry\n  }\n  throw err;\n}","preventionTips":["Re-read the file region immediately before writing whole-line patterns.","Match indentation exactly — same characters (tabs/spaces) and same depth.","Watch for stale file views after other tools or prior edits changed the file.","Avoid hand-typing lines; copy them from the actual source."],"tags":["edit-pattern","matching","whitespace","no-match"],"backgroundTag":"edit-pattern-no-match","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}