gitbutlerapp/gitbutler · error
Failed to parse patch
Error message
Failed to parse patch
What it means
Thrown by parseFileDiff when processFile (the diff-to-code-view parser) returns a falsy result for the given patch string. A non-empty patch that the parser cannot turn into a file diff structure indicates malformed, truncated, or unsupported diff content. The result is cached by version so re-parses with the same patch text are avoided.
Solutions
- Log/inspect the failing patch string to see why processFile rejects it (empty, truncated, or binary).
- Filter out empty or binary patches before calling parsePreparedDiffFile.
- Ensure the backend produces well-formed unified diffs; check for recent changes to the diff producer.
- Wrap parsePreparedDiffFile in try/catch and render a fallback 'diff unavailable' view per file.
Example fix
// before
const fileDiff = parsePreparedDiffFile(prepared);
// after
let fileDiff;
try {
fileDiff = parsePreparedDiffFile(prepared);
} catch {
fileDiff = null; // render fallback in the diff view
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!patch || patch.trim() === '') return null; // skip empty patches before parsing
Try / catch
try {
const fileDiff = parsePreparedDiffFile(prepared);
} catch {
renderDiffUnavailableFallback();
} Prevention
- Filter empty and binary patches before parsing
- Verify backend diff payloads are complete unified diffs
- Always render a per-file fallback so one bad patch doesn't break the view
When it happens
Trigger: Calling parseFileDiff (via parsePreparedDiffFile) with a patch string that processFile cannot parse — returns null/undefined.
Common situations: Truncated diff payloads from the backend, empty or whitespace-only patches slipping through preparation, binary-file diffs rendered as text, or an unsupported diff format produced by a git version change.
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Alternative hunks algorithms still didn't produce properly…
- Cannot compute diff specs for branch
- Cannot compute diff specs for committed hunks
- Cannot compute diff specs for stacks
- Cannot compute diff specs for worktree
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/9ec60c38d7f2aa98.
Report an issue: GitHub.
Appendix: source
Thrown at apps/lite/ui/src/routes/project/$id/workspace/diff-view.ts:118
selection: DiffLineSelection | null;
fileByItemId: DiffView["fileByItemId"];
diffStyle: DiffStyle;
}): CodeViewLineSelection | null => {
if (!selection) return null;
const file = fileByItemId.get(weakFileIdentityKey(selection.file));
if (!file) return null;
const range = selection.range ?? file.hunks[0]?.ranges[diffStyle];
return range ? { id: file.item.id, range } : null;
};
const parseFileDiff = (
patch: string,
version: string,
): CodeViewDiffItem<Annotation>["fileDiff"] => {
const parsed = processFile(patch, { cacheKey: version });
if (!parsed) throw new Error("Failed to parse patch");
return parsed;
};
/**
* Prepare stable file IDs and patch versions once for both review state and
* the rendered diff. Parsing remains separate so single-file mode only builds
* Pierre's diff shape for the selected file.
*/
export const prepareDiffFiles = ({
fileParent,
changes,
treeChangeDiffs,
}: PrepareDiffFilesDeps): Array<PreparedDiffFile> =>
treeChangeDiffs.flatMap((treeChangeDiff, index) => {
const change = changes[index];
if (change === undefined || treeChangeDiff === undefined) return [];
const file: FileAddress = { parent: fileParent, path: change.path };View on GitHub (pinned to 58e5313667)