paperclipai/paperclip · error
Codex thread response omitted thread.id
Error message
Codex thread response omitted thread.id
What it means
The Codex app-server driver throws this when the `thread/new` (session open) response does not contain a usable `thread.id` string. Paperclip requires a stable thread identifier to correlate all subsequent turns with the provider session, so an empty or missing id is treated as a protocol violation by the provider. The driver fails fast in `#openedThread` rather than returning a thread that cannot be addressed.
Source
Thrown at packages/paperclip-runner/src/drivers/codex/codex-app-server-driver-impl.ts:788
// supports, so the capability stays as advertised and the goal is merely
// unknown until the next call.
this.#options.onDiagnostic?.(
redactCodexDiagnostic(`thread goal probe failed: ${String(error)}`),
);
return undefined;
}
}
#openedThread(
response: Record<string, unknown>,
initialize: Record<string, unknown>,
workingDirectory: string,
collaborationMode: Record<string, unknown> | null,
): OpenedCodexThread {
const thread = record(response.thread);
const threadId = text(thread.id);
if (threadId.length === 0)
throw new Error("Codex thread response omitted thread.id");
const providerSessionId = text(thread.sessionId) || null;
if (
this.#options.requireProviderSessionIdentity &&
providerSessionId === null
) {
throw new Error(
`provider_initialize_protocol_error: provider=${this.#options.driverIdentity?.kind ?? "codex"} stage=session.open omitted provider session identity`,
);
}
const activePermissionProfile = record(thread.activePermissionProfile);
const permissionProfileId = text(activePermissionProfile.id);
const requestedMode = this.#options.requestedCollaborationMode ?? "default";
const requiredPermissionProfile =
text(createSecuredCodexThreadParams(workingDirectory, requestedMode, true, false, this.#options.environment).permissions);
if (
permissionProfileId.length > 0 &&
permissionProfileId !== requiredPermissionProfile
) {View on GitHub (pinned to 01ad858492)
Solutions
- Check the installed Codex app-server version and upgrade to one that returns thread.id in the thread/new response
- Log the raw response.thread payload before this point to confirm the provider actually omitted id
- If using a custom/proxy app-server, make it echo back a non-empty thread.id
- Update the adapter protocol expectations if Codex renamed the field
Example fix
// before (provider response)
{ "thread": { "sessionId": "s-1" } }
// after (correct provider response)
{ "thread": { "id": "thr_abc123", "sessionId": "s-1" } } Defensive patterns
Strategy: try-catch
Validate before calling
const thread = record(response.thread);
if (!thread || typeof thread.id !== "string" || thread.id.length === 0) {
throw new Error("provider response missing thread.id");
} Type guard
function hasThreadId(t: unknown): t is { id: string } {
return typeof t === "object" && t !== null && typeof (t as { id?: unknown }).id === "string" && (t as { id: string }).id.length > 0;
} Try / catch
try {
const opened = await driver.opened(...);
} catch (err) {
if (err.message.includes("omitted thread.id")) {
logProviderProtocolViolation(response); // capture raw payload, retry with healthy provider
}
throw err;
} Prevention
- Pin and health-check the Codex app-server version before admitting sessions
- Contract-test provider responses against the expected thread/new schema
- Log raw provider payloads at session-open for diagnosability
When it happens
Trigger: Calling `opened()` after starting a Codex app-server session when the provider's response `thread` object lacks an `id` field, or `text(thread.id)` returns an empty string (e.g. provider returned `{}` or `id: ""`).
Common situations: Running against an older or nonstandard Codex app-server build whose thread/new payload schema differs; a version mismatch between the adapter protocol expectations and the installed Codex binary; mocking/stub drivers that omit the field.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- native_session_multi_run_unavailable
- provider_initialize_protocol_error
- Codex turn response omitted turn.id
- Codex turn identity changed during start
- Codex turn response omitted turn.id
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/da7826298897b0bb.
Report an issue: GitHub.