{"record":{"id":"63c6629cdcf073bf","repo":"can1357/oh-my-pi","slug":"line-hint-hunk-oldstartline-is-out-of-range-for","errorCode":null,"errorMessage":"Line hint ${hunk.oldStartLine} is out of range for ${path} (line numbers start at 1)","messagePattern":"Line hint (.+?) is out of range for (.+?) \\(line numbers start at 1\\)","errorType":"validation","errorClass":"ApplyPatchError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/edit/modes/patch.ts","lineNumber":1101,"sourceCode":"}\n\n/**\n * Compute replacements needed to transform originalLines using the diff hunks.\n */\nfunction computeReplacements(\n\toriginalLines: string[],\n\tpath: string,\n\thunks: DiffHunk[],\n\tallowFuzzy: boolean,\n): { replacements: Replacement[]; warnings: string[] } {\n\tconst replacements: Replacement[] = [];\n\tconst warnings: string[] = [];\n\tlet lineIndex = 0;\n\n\tfor (const hunk of hunks) {\n\t\tlet contextIndex: number | undefined;\n\t\tif (hunk.oldStartLine !== undefined && hunk.oldStartLine < 1) {\n\t\t\tthrow new ApplyPatchError(\n\t\t\t\t`Line hint ${hunk.oldStartLine} is out of range for ${path} (line numbers start at 1)`,\n\t\t\t);\n\t\t}\n\t\tif (hunk.newStartLine !== undefined && hunk.newStartLine < 1) {\n\t\t\tthrow new ApplyPatchError(\n\t\t\t\t`Line hint ${hunk.newStartLine} is out of range for ${path} (line numbers start at 1)`,\n\t\t\t);\n\t\t}\n\t\tconst lineHint = hunk.oldStartLine;\n\t\tconst allowAggressiveFallbacks = hunk.changeContext !== undefined || lineHint !== undefined || hunk.isEndOfFile;\n\t\tconst fallbackVariants = filterFallbackVariants(buildFallbackVariants(hunk), allowAggressiveFallbacks);\n\t\tif (lineHint !== undefined && hunk.changeContext === undefined && !hunk.hasContextLines) {\n\t\t\tlineIndex = Math.max(0, Math.min(lineHint - 1, originalLines.length - 1));\n\t\t}\n\n\t\t// If hunk has a changeContext, find it and adjust lineIndex\n\t\tif (hunk.changeContext !== undefined) {\n\t\t\t// Use hierarchical context matching for nested @@ anchors and space-separated contexts","sourceCodeStart":1083,"sourceCodeEnd":1119,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/edit/modes/patch.ts#L1083-L1119","documentation":"computeReplacements validates the hunk's @@ line hint before matching. If hunk.oldStartLine is defined and less than 1 (0 or negative), the hint cannot be a valid 1-indexed line number, so an ApplyPatchError is thrown. The hunk header must carry a start line of at least 1.","triggerScenarios":"A diff hunk header like `@@ -0,0` or a computed oldStartLine of 0/negative is fed into computeReplacements; malformed patch generation or off-by-one conversion from 0-indexed to 1-indexed coordinates.","commonSituations":"Programmatic patch construction where line numbers were computed 0-indexed and passed unconverted; new-file patches mislabeled as updates; hand-edited diff headers.","solutions":["Fix the hunk header to use a 1-indexed start line (e.g. `@@ -1,5 +1,6 @@`).","If the target is a brand-new file, use *** Add File with no line hints instead of an Update hunk with line 0.","Convert any 0-indexed line counters to 1-indexed before building the patch.","Drop the line hint entirely — the patcher can locate the change by context lines alone."],"exampleFix":"// before\n@@ -0,3 +0,4 @@\n context\n\n// after\n@@ -1,3 +1,4 @@\n context","handlingStrategy":"validation","validationCode":"if (hunk.oldStartLine !== undefined && hunk.oldStartLine < 1) {\n  throw new Error(`oldStartLine must be >= 1, got ${hunk.oldStartLine}`);\n}","typeGuard":"function hasValidOldHint(hunk: DiffHunk): boolean {\n  return hunk.oldStartLine === undefined || hunk.oldStartLine >= 1;\n}","tryCatchPattern":"try {\n  applyPatch(patch);\n} catch (err) {\n  if (err instanceof ApplyPatchError && err.message.includes('Line hint') && err.message.includes('start at 1')) {\n    // fix hunk headers to 1-indexed and retry once\n  } else throw err;\n}","preventionTips":["Always emit 1-indexed line numbers in @@ headers.","Use standard diff tools (git diff) to generate headers.","Drop line hints when unsure — context lines alone are usually sufficient.","Add a unit check on patch builders that converts 0-indexed values."],"tags":["patch","validation","line-numbers"],"backgroundTag":"patch-line-hint-out-of-range","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}