can1357/oh-my-pi · error · ApplyPatchError

Line hint ${hunk.newStartLine} is out of range for ${path} (

Error message

Line hint ${hunk.newStartLine} is out of range for ${path} (line numbers start at 1)

What it means

Identical validation to error 1182 but for the new-side hunk header: hunk.newStartLine is defined and less than 1. The patcher requires 1-indexed positive line hints on both sides of the @@ header. Thrown before any file matching happens.

Source

Thrown at packages/coding-agent/src/edit/modes/patch.ts:1106

function computeReplacements(
	originalLines: string[],
	path: string,
	hunks: DiffHunk[],
	allowFuzzy: boolean,
): { replacements: Replacement[]; warnings: string[] } {
	const replacements: Replacement[] = [];
	const warnings: string[] = [];
	let lineIndex = 0;

	for (const hunk of hunks) {
		let contextIndex: number | undefined;
		if (hunk.oldStartLine !== undefined && hunk.oldStartLine < 1) {
			throw new ApplyPatchError(
				`Line hint ${hunk.oldStartLine} is out of range for ${path} (line numbers start at 1)`,
			);
		}
		if (hunk.newStartLine !== undefined && hunk.newStartLine < 1) {
			throw new ApplyPatchError(
				`Line hint ${hunk.newStartLine} is out of range for ${path} (line numbers start at 1)`,
			);
		}
		const lineHint = hunk.oldStartLine;
		const allowAggressiveFallbacks = hunk.changeContext !== undefined || lineHint !== undefined || hunk.isEndOfFile;
		const fallbackVariants = filterFallbackVariants(buildFallbackVariants(hunk), allowAggressiveFallbacks);
		if (lineHint !== undefined && hunk.changeContext === undefined && !hunk.hasContextLines) {
			lineIndex = Math.max(0, Math.min(lineHint - 1, originalLines.length - 1));
		}

		// If hunk has a changeContext, find it and adjust lineIndex
		if (hunk.changeContext !== undefined) {
			// Use hierarchical context matching for nested @@ anchors and space-separated contexts
			const result = findHierarchicalContext(originalLines, hunk.changeContext, lineIndex, lineHint, allowFuzzy);
			const idx = result.index;
			contextIndex = idx;

			if (idx === undefined || (result.matchCount !== undefined && result.matchCount > 1)) {

View on GitHub (pinned to 9690622007)

Solutions

  1. Correct the new-side start line in the @@ header to be >= 1.
  2. Regenerate the patch with a standard diff tool (git diff) to get valid headers.
  3. Remove the line hints and rely on context lines for locating the change.
  4. If the patch creates a new file, switch to *** Add File semantics.

Example fix

// before
@@ -10,4 +0,2 @@

// after
@@ -10,4 +11,2 @@
Defensive patterns

Strategy: validation

Validate before calling

if (hunk.newStartLine !== undefined && hunk.newStartLine < 1) {
  throw new Error(`newStartLine must be >= 1, got ${hunk.newStartLine}`);
}

Type guard

function hasValidNewHint(hunk: DiffHunk): boolean {
  return hunk.newStartLine === undefined || hunk.newStartLine >= 1;
}

Try / catch

try {
  applyPatch(patch);
} catch (err) {
  if (err instanceof ApplyPatchError && err.message.includes('Line hint') && err.message.includes('start at 1')) {
    // sanitize headers to 1-indexed values, then retry
  } else throw err;
}

Prevention

When it happens

Trigger: A hunk header `@@ -1,5 +0,3 @@` (or negative new start) is parsed and passed to computeReplacements; 0-indexed new-side line numbers produced by a patch generator.

Common situations: Custom diff writers that emit 0-indexed new-line coordinates; pure-insertion hunks mislabeled with start line 0; diffs converted between tools that disagree on indexing.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/9987d42a493b5e94. Report an issue: GitHub.