Summary
The diff panel can remain on Loading checkpoint diff... for an extended period when the UI already has a checkpoint summary for a turn, but the underlying checkpoint ref is not yet available on the server/filesystem.
Observed behavior
In the right-hand diff panel, selecting a turn or opening the conversation diff sometimes shows:
Loading checkpoint diff...
and does not immediately resolve to either:
- the rendered patch
- a clear error state
- or a
No patch available for this selection. state
Expected behavior
If a checkpoint is not yet ready or is missing, the UI should not appear stuck in a loading state.
It should either:
- only offer diffs for truly diffable checkpoints, or
- show a clear temporary/unavailable state instead of a prolonged loading indicator
Likely cause
The frontend includes all checkpoint summaries from thread state, regardless of checkpoint status, and immediately requests the diff.
The server rejects the diff request when:
- the requested turn count exceeds the current checkpoint turn count
- the checkpoint ref is unavailable
- the filesystem checkpoint ref is unavailable
The frontend currently classifies those responses as temporarily unavailable and retries repeatedly, which keeps the panel in a loading state for too long.
Why the obvious fix is only a partial fix
Filtering to status === "ready" in the web app is probably the right short-term mitigation, but it is not the full design fix.
The deeper issue is that the UI is currently forced to infer "diffable" from incomplete state. A checkpoint being present in the snapshot is not the same thing as the checkpoint being actually usable for diff queries.
This makes the current state model blurry across:
- projection/snapshot state
- diff query availability
- loading vs temporarily unavailable vs missing vs error UI states
Relevant code
Frontend:
apps/web/src/components/DiffPanel.tsx
apps/web/src/lib/providerReactQuery.ts
apps/web/src/store.ts
Backend:
apps/server/src/checkpointing/Layers/CheckpointDiffQuery.ts
Suggested fixes
Short-term:
- Filter diffable checkpoints to
status === "ready" in the web app.
- Surface a temporary unavailable state in the diff panel instead of showing only loading during retries.
- Reduce or specialize retry behavior for checkpoint-diff requests.
Longer-term:
- Tighten the state contract so the UI does not need to infer whether a checkpoint is actually diffable.
- Model
loading, temporarily unavailable, missing, error, and ready as distinct UI states.
- Make snapshot visibility and diff availability align more explicitly.
Summary
The diff panel can remain on
Loading checkpoint diff...for an extended period when the UI already has a checkpoint summary for a turn, but the underlying checkpoint ref is not yet available on the server/filesystem.Observed behavior
In the right-hand diff panel, selecting a turn or opening the conversation diff sometimes shows:
Loading checkpoint diff...and does not immediately resolve to either:
No patch available for this selection.stateExpected behavior
If a checkpoint is not yet ready or is missing, the UI should not appear stuck in a loading state.
It should either:
Likely cause
The frontend includes all checkpoint summaries from thread state, regardless of checkpoint status, and immediately requests the diff.
The server rejects the diff request when:
The frontend currently classifies those responses as temporarily unavailable and retries repeatedly, which keeps the panel in a loading state for too long.
Why the obvious fix is only a partial fix
Filtering to
status === "ready"in the web app is probably the right short-term mitigation, but it is not the full design fix.The deeper issue is that the UI is currently forced to infer "diffable" from incomplete state. A checkpoint being present in the snapshot is not the same thing as the checkpoint being actually usable for diff queries.
This makes the current state model blurry across:
Relevant code
Frontend:
apps/web/src/components/DiffPanel.tsxapps/web/src/lib/providerReactQuery.tsapps/web/src/store.tsBackend:
apps/server/src/checkpointing/Layers/CheckpointDiffQuery.tsSuggested fixes
Short-term:
status === "ready"in the web app.Longer-term:
loading,temporarily unavailable,missing,error, andreadyas distinct UI states.