can1357/oh-my-pi · error · ParseError

Line numbers must be >= 1 (got ${newStartLine})

Error message

Line numbers must be >= 1 (got ${newStartLine})

What it means

Same enforcement as the old-side check, but for the new start line: after header parsing, if newStartLine is defined and less than 1 the parser throws. It guarantees both sides of the hunk anchor at a valid 1-based position before content lines are consumed.

Source

Thrown at packages/coding-agent/src/edit/diff.ts:620

		startIndex = 1;
	} else if (isHeaderLine) {
		const contextValue = headerTrimmed.slice(2).trim();
		if (contextValue.length > 0) {
			changeContexts.push(contextValue);
		}
		startIndex = 1;
	} else {
		if (!allowMissingContext) {
			throw new ParseError(`Expected hunk to start with @@ context marker, got: '${lines[0]}'`, lineNumber);
		}
		startIndex = 0;
	}

	if (oldStartLine !== undefined && oldStartLine < 1) {
		throw new ParseError(`Line numbers must be >= 1 (got ${oldStartLine})`, lineNumber);
	}
	if (newStartLine !== undefined && newStartLine < 1) {
		throw new ParseError(`Line numbers must be >= 1 (got ${newStartLine})`, lineNumber);
	}

	while (startIndex < lines.length) {
		const nextLine = lines[startIndex];
		if (!nextLine.startsWith("@@")) {
			break;
		}
		const trimmed = nextLine.trimEnd();
		if (trimmed.startsWith(CHANGE_CONTEXT_MARKER)) {
			const nestedContext = trimmed.slice(CHANGE_CONTEXT_MARKER.length);
			if (nestedContext.trim().length > 0) {
				changeContexts.push(nestedContext);
			}
			startIndex++;
		} else if (trimmed === EMPTY_CHANGE_CONTEXT_MARKER) {
			startIndex++;
		} else {
			break;

View on GitHub (pinned to 9690622007)

Solutions

  1. Renumber the new-side start line to >= 1 (e.g. '+1,0' instead of '+0,0').
  2. For pure deletions, anchor the new side at line 1 with count 0.
  3. Regenerate the diff with standard tooling and re-check the header.
  4. Pre-validate both start numbers with a regex + Number check before parsing.

Example fix

// before
@@ -1,5 +0,0 @@
-old line
// after
@@ -1,5 +1,0 @@
-old line
Defensive patterns

Strategy: validation

Validate before calling

const m = header.match(/^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/);
if (m && Number(m[1]) < 1) {
  throw new Error(`new start line must be >= 1, got ${m[1]}`);
}

Try / catch

try {
  hunks = parseDiffHunks(diff);
} catch (err) {
  if (err instanceof ParseError && err.message.includes("(got ")) {
    // patch the header to a 1-based anchor and retry
  } else throw err;
}

Prevention

When it happens

Trigger: parseOneHunk with a unified header like '@@ -1,5 +0,0 @@' or any header whose new-side start is 0/negative.

Common situations: Git-style file-deletion or file-creation hunks that use '+0,0' / '-0,0' conventions, which this parser rejects; hand-written diffs counting from zero; custom diff generators emitting 0-based new-side numbers.

Related errors


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