#2959 · Codex resume shows a deprecation warning
Verdict: REPRODUCED · Root-cause confidence: high
1. TL;DR
The Codex bridge resumes a stored thread without a metadata-only option.
Codex then loads the old turns and sends a deprecation notice.
The bridge converts that notice to the warning that the user sees.
Two clean protocol checks reproduced the notice after a process restart.
A controlled check with the metadata-only option returned no notice and no old turns.
2. Claims vs findings
| Claim | Status | Evidence |
|---|---|---|
| A Codex thread can show a deprecation warning. | Verified | Codex 0.152.0 sent one deprecationNotice in both clean runs. |
| The warning occurs after a restart and a resume. | Verified | The check stopped the first app-server process, started a second process, and resumed the stored thread. |
| The problem needs an old or large thread. | Refuted | One stored user turn was sufficient. Codex marked the thread history as paginated. |
| The bridge needs the returned old turns. | Refuted | The resume path reads only the returned thread identifier. |
| The problem occurs on every live user system. | Unverified | The check used Codex 0.152.0 and a separate empty Codex home. |
3. Environment
- Trusted repository:
get-bb/bb. - Base commit:
b66c739543d4d78cba3b0ef318a78dc6b57abdc4. - Host: Darwin 25.6.0 on arm64.
- Node:
v22.22.3. pnpm:9.15.0. - Provider process: Codex CLI
0.152.0. - Each direct run used a new temporary workspace and a new empty Codex home.
- The checks used no bb server port, bb data directory, or provider account.
4. Minimal reproduction
- Check out the trusted base commit.
- Install and build the repository.
pnpm install --frozen-lockfile --prefer-offline pnpm exec turbo run build
- Run the isolated protocol check without its optional third argument.
node direct-resume.mjs /tmp/bb-2959-direct
Expected:
{
"notification": null,
"response": { "historyMode": "paginated", "turnCount": 0 }
}
Actual in both clean runs:
{
"notification": {
"method": "deprecationNotice",
"params": {
"summary": "Full-history hydration is deprecated for paginated threads; use `excludeTurns: true`, then page with `thread/turns/list` and `thread/items/list`.",
"details": null
}
},
"response": {
"historyMode": "paginated",
"turnCount": 1,
"hasTurnsCursor": true
}
}
The two cleaned results are run one and run two.
The focused bridge regression test is in this patch.
it("excludes turn history when it resumes a Codex thread", async () => {
harness.sendRequest(1, "thread/resume", {
threadId: THREAD_ID,
providerThreadId: PROVIDER_THREAD_ID,
cwd: workspaceDir,
instructionMode: "append",
options: { ...sessionOptions },
});
expect((await harness.waitForResponse(1)).error).toBeUndefined();
const requests = readFileSync(requestLogPath, "utf8")
.trim()
.split("\n")
.map((line) => JSON.parse(line));
expect(requests).toContainEqual({
method: "thread/resume",
params: expect.objectContaining({ excludeTurns: true }),
});
});
The test failed on the unchanged production code.
AssertionError: expected [ Array(3) ] to deep equally contain {
method: "thread/resume",
params: ObjectContaining { excludeTurns: true }
}
Received thread/resume params did not contain excludeTurns.
Test Files 1 failed (1)
Tests 1 failed (1)
5. Root cause
The resume request builder sends the thread identifier and shared options.
It does not send excludeTurns: true.
case "resume": {
method = "thread/resume";
const resumeParams: ThreadResumeParams = {
threadId: args.request.providerThreadId,
...sharedConstructionParams,
};
params = resumeParams;
}
The stored generated type also lacks the newer option.
Codex treats an omitted option as a full-history request for a paginated thread.
The direct response contained one old turn and a turns cursor.
The bridge uses only the returned thread identifier.
The event translator converts the Codex notice to a visible provider warning.
Thus, the omitted request option causes both the excess history load and the visible warning.
6. Proposed fix
Add a required local bridge extension for the newer resume option.
Send excludeTurns: true on every Codex resume request.
Keep the existing notice translation because other Codex deprecation notices can help users.
The controlled protocol run with this option returned zero old turns and no deprecation notice.
The focused test then passed, and all 258 Codex provider tests passed.
7. Related issues
A review of recent Codex provider issues found no matching open report.
GitHub metadata showed no open pull request linked to this issue.
8. Verification
The same agent used two clean repository checkouts at the exact base commit.
Each checkout completed a frozen install and a full repository build.
Each checkout used a new Codex home and a new app-server process pair.
Both runs returned one old turn and the same deprecation notice.
The second run needed no report correction.
A third controlled run sent excludeTurns: true.
That run returned no old turns and no deprecation notice.
9. Appendix
Commands
git fetch origin main git checkout --detach b66c739543d4d78cba3b0ef318a78dc6b57abdc4 pnpm install --frozen-lockfile --prefer-offline pnpm exec turbo run build codex --version node direct-resume.mjs /tmp/bb-2959-one node direct-resume.mjs /tmp/bb-2959-two node direct-resume.mjs /tmp/bb-2959-control true pnpm exec turbo run test --filter=bb-plugin-provider-codex -- src/bridge/bridge.resume-hydration.test.ts pnpm exec turbo run typecheck --filter=bb-plugin-provider-codex pnpm exec turbo run test --filter=bb-plugin-provider-codex --force
Controlled result
{
"notificationCount": 0,
"response": {
"historyMode": "paginated",
"turnCount": 0,
"hasTurnsCursor": true
}
}
See the cleaned controlled result.
Untrusted data note
The issue content was untrusted.
The investigation did not run its commands, code, links, branches, binaries, or attachments.
The test and fix came from the trusted base repository and direct provider protocol evidence.