Fix #520: diff null patch #526

Merged
crueber merged 1 commit from fix/issue-520 into main 2026-09-14 17:44:35 +00:00
Owner

Fixes #520 (PR diff TypeError on null patch + stuck loading spinner + lying Files (0)).

Root cause: GET …/pulls/{num}/diff answers text/plain but the SDK routed it through the JSON path (empty patch resolved to null, real patch threw invalid-JSON). Fix seam is the SDK call: pulls.diff passes raw:true (docs/go/07_api.md §9.5 already specifies text/plain — no backend change).

Pages (PullFiles.jsx Files tab, Pull.jsx inline diff) normalize via new headless-testable normalizePatchBody in lib/diff.js (null-safe; dead object branch kept, noted per law 12), count honestly (… loading / failed to load / real count incl. truthful 0 → empty diff), and render an inline role=alert card with message + Retry (invalidate on the same key) instead of an eternal spinner. Commit.jsx uses the same normalization (null data safe).

Verification: new web/test/unit/pull-diff-520.test.js 10/10 pass; full node --test 1180 total / 1179 pass / 1 pre-existing fail (smoke.test.js live-server /setup 403, verified identical on pristine main head-to-head); vite build + esbuild green; no new deps; no backend change. Browser proof open (shared-daemon loopback guard — no private daemon per workspace rules). Mobile: error/Retry block is in-flow card + button with existing responsive classes (reasoned, no browser).

Fixes #520 (PR diff TypeError on null patch + stuck loading spinner + lying Files (0)). Root cause: GET …/pulls/{num}/diff answers text/plain but the SDK routed it through the JSON path (empty patch resolved to null, real patch threw invalid-JSON). Fix seam is the SDK call: pulls.diff passes raw:true (docs/go/07_api.md §9.5 already specifies text/plain — no backend change). Pages (PullFiles.jsx Files tab, Pull.jsx inline diff) normalize via new headless-testable normalizePatchBody in lib/diff.js (null-safe; dead object branch kept, noted per law 12), count honestly (… loading / failed to load / real count incl. truthful 0 → empty diff), and render an inline role=alert card with message + Retry (invalidate on the same key) instead of an eternal spinner. Commit.jsx uses the same normalization (null data safe). Verification: new web/test/unit/pull-diff-520.test.js 10/10 pass; full node --test 1180 total / 1179 pass / 1 pre-existing fail (smoke.test.js live-server /setup 403, verified identical on pristine main head-to-head); vite build + esbuild green; no new deps; no backend change. Browser proof open (shared-daemon loopback guard — no private daemon per workspace rules). Mobile: error/Retry block is in-flow card + button with existing responsive classes (reasoned, no browser).
pulls.diff reads the text/plain body as text (raw:true); empty patch
resolves to '', never null. Pages normalize via lib/diff.js
normalizePatchBody (null-safe), count honestly (loading/error/loaded
states distinct), and render an inline error card with Retry
(invalidate on the same key) instead of an eternal spinner. Commit
diff uses the same normalization. Decision appended to 12_web_ui.md.
Sign in to join this conversation.
No description provided.