{"record":{"id":"5d9c464436e931c6","repo":"can1357/oh-my-pi","slug":"line-hint-linehintforinsertion-is-out-of-range-5d9c46","errorCode":null,"errorMessage":"Line hint ${lineHintForInsertion} is out of range for insertion in ${path} (file has ${originalLines.length} lines)","messagePattern":"Line hint (.+?) is out of range for insertion in (.+?) \\(file has (.+?) lines\\)","errorType":"validation","errorClass":"ApplyPatchError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/edit/modes/patch.ts","lineNumber":1187,"sourceCode":"\t\tif (hunk.oldLines.length === 0) {\n\t\t\t// Pure addition - prefer changeContext position, then line hint, then end of file\n\t\t\tlet insertionIdx: number;\n\t\t\tif (hunk.changeContext !== undefined) {\n\t\t\t\t// changeContext was processed above; lineIndex is set to the context line or after it\n\t\t\t\tinsertionIdx = lineIndex;\n\t\t\t} else {\n\t\t\t\tconst lineHintForInsertion = hunk.oldStartLine ?? hunk.newStartLine;\n\t\t\t\tif (lineHintForInsertion !== undefined) {\n\t\t\t\t\t// Reject if line hint is out of range for insertion\n\t\t\t\t\t// Valid insertion points are 1 to (file length + 1) for 1-indexed hints\n\t\t\t\t\tif (lineHintForInsertion < 1) {\n\t\t\t\t\t\tthrow new ApplyPatchError(\n\t\t\t\t\t\t\t`Line hint ${lineHintForInsertion} is out of range for insertion in ${path} ` +\n\t\t\t\t\t\t\t\t`(line numbers start at 1)`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tif (lineHintForInsertion > originalLines.length + 1) {\n\t\t\t\t\t\tthrow new ApplyPatchError(\n\t\t\t\t\t\t\t`Line hint ${lineHintForInsertion} is out of range for insertion in ${path} ` +\n\t\t\t\t\t\t\t\t`(file has ${originalLines.length} lines)`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tinsertionIdx = Math.max(0, lineHintForInsertion - 1);\n\t\t\t\t} else {\n\t\t\t\t\tinsertionIdx =\n\t\t\t\t\t\toriginalLines.length > 0 && originalLines[originalLines.length - 1] === \"\"\n\t\t\t\t\t\t\t? originalLines.length - 1\n\t\t\t\t\t\t\t: originalLines.length;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treplacements.push({ startIndex: insertionIdx, oldLen: 0, newLines: [...hunk.newLines] });\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Try to find the old lines in the file","sourceCodeStart":1169,"sourceCodeEnd":1205,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/edit/modes/patch.ts#L1169-L1205","documentation":"Companion to error 1186: for a pure-insertion hunk with a line hint, the hint may point at most one past the end of the file (file length + 1, i.e. append). If lineHintForInsertion exceeds originalLines.length + 1, there is no such insertion point and the patcher throws, reporting the actual file length.","triggerScenarios":"An addition-only hunk whose oldStartLine/newStartLine hint is greater than the target file's line count + 1, with no @@ anchor to position it.","commonSituations":"Patch written against an older, longer revision of the file that has since been truncated or rewritten; hallucinated line numbers from an LLM; patch reused across similar files of different lengths.","solutions":["Re-read the file, count its lines, and set the hint to a value <= file length + 1 (length + 1 appends).","Drop the line hint to append at end of file.","Anchor the insertion with a @@ changeContext instead of a raw line number.","Regenerate the patch from the file's current content."],"exampleFix":"// before (file has 42 lines)\n@@ -99,0 +99,3 @@\n+appended lines\n\n// after\n@@ -43,0 +43,3 @@\n+appended lines","handlingStrategy":"validation","validationCode":"const lineCount = (await Bun.file(path).text()).split('\\n').length;\nif (lineHint !== undefined && lineHint > lineCount + 1) {\n  throw new Error(`Insertion hint ${lineHint} exceeds ${path} (${lineCount} lines); max is ${lineCount + 1}.`);\n}","typeGuard":"function isValidInsertionHint(hint: number, fileLineCount: number): boolean {\n  return hint >= 1 && hint <= fileLineCount + 1;\n}","tryCatchPattern":"try {\n  applyPatch(patch);\n} catch (err) {\n  if (err instanceof ApplyPatchError && err.message.includes('file has')) {\n    // re-read file, clamp hint to lineCount + 1 (append), retry\n  } else throw err;\n}","preventionTips":["Re-read the file to get its current length before hinting insertions.","Use file length + 1 to append rather than a large guessed number.","Regenerate patches after the file has been truncated or rewritten.","Anchor insertions with context instead of absolute line numbers."],"tags":["patch","insertion","line-numbers","stale-content"],"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"}