Paginated history projector rejects legacy duration objects with `invalid type: map, expected f64`
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
What version of Codex is running?
- Affected rollouts were written by Codex Desktop / CLI
0.146.1 - The incompatibility was observed after opening the same paginated threads with a newer Desktop app-server (
0.149.1) - Current installed CLI used for diagnostics:
codex-cli 0.150.1
What platform is your computer?
Ubuntu 22.04.5 LTS, Linux 6.8.0, x86_64.
What issue are you seeing?
Long-running local conversations created by an older Codex process disappear completely or become truncated in the Desktop GUI even though the durable rollout JSONL still contains the full transcript.
The paginated history projector repeatedly logs:
skipping rejected rollout line while projecting "<redacted rollout path>":
invalid type: map, expected f64 at line 1 column <varies>
The rejected records contain command-execution duration values serialized by the older writer as a Rust-style duration object:
"duration":{"secs":0,"nanos":137321817}
The newer projector appears to deserialize the same field as a floating-point number, equivalent to:
"duration":0.137321817
Because projection stops/rejects these otherwise valid records, the GUI does not show conversation turns that are still present on disk. This can look like chat history loss even though the source rollout is intact.
In one sanitized local repair batch, 11 rollout files contained 723 values in the legacy {"secs": ..., "nanos": ...} representation. The affected thread metadata used history_mode = "paginated".
What steps can reproduce the bug?
- Use Codex Desktop / CLI
0.146.1to create or continue a paginated conversation that runs local commands. - Ensure the rollout contains a completed command item whose
durationis serialized as:{"secs":3,"nanos":72761183} - Upgrade to a newer Codex Desktop/app-server version whose history projection schema expects
durationto be anf64. - Reopen the old conversation or trigger history projection.
- Observe repeated
invalid type: map, expected f64errors. - Observe that the GUI history is missing or stops before the rejected records even though the rollout JSONL remains complete.
What is the expected behavior?
Paginated history projection should remain backward compatible with rollout records written by supported older Codex versions.
The duration deserializer should accept both:
{"secs":3,"nanos":72761183}
and:
3.072761183
Alternatively, a nonessential duration field should be normalized or omitted without rejecting the complete history item or preventing later turns from appearing.
What is the actual behavior?
The projector rejects affected rollout lines with:
invalid type: map, expected f64
The source transcript remains on disk, but the Desktop conversation pane does not materialize it correctly.
Local validation and workaround
Before repair, the rollout files and SQLite databases were backed up. The local workaround was:
- Stop old writers.
- Convert each duration map using:
seconds = secs + nanos / 1_000_000_000 - Reset/rebuild the affected paginated history projections.
- Restart the Desktop app-server.
After conversion, the conversations became visible again.
Post-repair validation:
PRAGMA integrity_check: ok
projected turns: 930
projected items: 9374
invalid item_json rows: 0
This indicates that the durable conversation data and SQLite structure were healthy; the incompatible duration representation was the projection blocker.
Suggested fix
- Use a backward-compatible/untagged duration deserializer accepting both numeric seconds and
{secs, nanos}. - Normalize legacy duration values during projection without rewriting the source rollout.
- Continue projecting when a nonessential telemetry/timing field is incompatible.
- Add a regression fixture containing a
0.146.1command-execution record. - Consider a supported history projection repair/rebuild command so users do not need to edit SQLite or rollout JSONL manually.
Related issues
- #40342 — paginated projection stops at a different record type (
token_count) - #38792 — older projection cursor desynchronization is not automatically repaired
- #35746 — inconsistent paginated rollout decoding paths
This report does not include the original database or rollout files because they contain private conversation and command output. Thread IDs, local usernames, absolute paths, request IDs, and conversation text have been removed.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the paginated history projection and duration deserialization path that emits invalid type: map, expected f64; the issue does not name a source file or test. Trace how command-execution records are decoded, then inspect the related projection fixtures and the 0.146.1 regression case described here. Done means both numeric seconds and {secs, nanos} durations project without dropping later turns, with a regression test covering the legacy record.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- backend, databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100