can1357/oh-my-pi · error · ParseError
Line numbers in @@ header must be >= 1
Error message
Line numbers in @@ header must be >= 1
What it means
This ParseError is thrown by parseOneHunk when a hunk starts with a standard unified-diff '@@ -a,b +c,d @@' header whose old or new start line number is less than 1. The parser requires every line number in the header to be a positive 1-based index; 0 or negative values are invalid in unified diffs. The library throws so callers get a precise, line-attributed message instead of applying a patch at a bogus location.
Source
Thrown at packages/coding-agent/src/edit/diff.ts:576
throw new ParseError("Diff does not contain any lines", lineNumber);
}
const changeContexts: string[] = [];
let oldStartLine: number | undefined;
let newStartLine: number | undefined;
let startIndex: number;
const headerLine = lines[0];
const headerTrimmed = headerLine.trimEnd();
const isHeaderLine = headerLine.startsWith("@@");
const unifiedHeader = isHeaderLine ? parseUnifiedHunkHeader(headerTrimmed) : undefined;
const isEmptyContextMarker = /^@@\s*@@$/.test(headerTrimmed);
if (isHeaderLine && (headerTrimmed === EMPTY_CHANGE_CONTEXT_MARKER || isEmptyContextMarker)) {
startIndex = 1;
} else if (unifiedHeader) {
if (unifiedHeader.oldStartLine < 1 || unifiedHeader.newStartLine < 1) {
throw new ParseError("Line numbers in @@ header must be >= 1", lineNumber);
}
if (unifiedHeader.changeContext) {
changeContexts.push(unifiedHeader.changeContext);
}
oldStartLine = unifiedHeader.oldStartLine;
newStartLine = unifiedHeader.newStartLine;
startIndex = 1;
} else if (isHeaderLine && headerTrimmed.startsWith(CHANGE_CONTEXT_MARKER)) {
const contextValue = headerTrimmed.slice(CHANGE_CONTEXT_MARKER.length);
const trimmedContextValue = contextValue.trim();
const normalizedContextValue = trimmedContextValue.replace(/^@@\s*/u, "");
const lineHintMatch = normalizedContextValue.match(LINE_HINT_REGEX);
if (lineHintMatch) {
oldStartLine = Number(lineHintMatch[1]);
newStartLine = oldStartLine;
if (oldStartLine < 1) {
throw new ParseError("Line hint must be >= 1", lineNumber);View on GitHub (pinned to 9690622007)
Solutions
- Renumber the hunk header so both start lines are >= 1 (new/empty files typically use '+1,N').
- If the patch targets a brand-new file, start the hunk at line 1 rather than 0.
- Regenerate the patch with the producing tool instead of hand-editing the header.
- Wrap the parse in try-catch for ParseError and surface the failing line number to the user.
Example fix
// before @@ -0,0 +1,3 @@ +new line // after @@ -1,3 +1,3 @@ new line
Defensive patterns
Strategy: validation
Validate before calling
const m = firstLine.match(/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/);
if (m && (Number(m[1]) < 1 || Number(m[2]) < 1)) {
throw new Error(`Hunk header start lines must be >= 1, got -${m[1]} +${m[2]}`);
} Try / catch
try {
hunks = parseDiffHunks(diff);
} catch (err) {
if (err instanceof ParseError && err.message.includes("must be >= 1")) {
// surface err.lineNumber and the offending header to the user / fix generator
} else throw err;
} Prevention
- Always generate headers with 1-based line numbers; never emit 0.
- For new files, use '+1,N' for the new side.
- Test your diff generator against empty-file and file-creation cases.
When it happens
Trigger: Calling parseDiffHunks or parseOneHunk with a diff whose first line matches UNIFIED_HUNK_HEADER_REGEX but contains a start line of 0 or a negative number, e.g. '@@ -0,0 +1,3 @@' or '@@ -5 +0 @@'.
Common situations: Hand-written patches where the author counts lines from 0; diffs generated against an empty/new file and mis-computed by custom tooling; tools that emit '@@ -0,0' for file-creation hunks (valid in git but rejected here since it implies insert-at-zero).
Related errors
- Line hint must be >= 1
- Line numbers must be >= 1 (got ${oldStartLine})
- Line numbers must be >= 1 (got ${newStartLine})
- Unknown changelog category: ${raw}
- No JSON payload found in response
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/1ff1732274d4c8fe.
Report an issue: GitHub.