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

  1. Check the installed Codex app-server version and upgrade to one that returns thread.id in the thread/new response
  2. Log the raw response.thread payload before this point to confirm the provider actually omitted id
  3. If using a custom/proxy app-server, make it echo back a non-empty thread.id
  4. 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

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


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/da7826298897b0bb. Report an issue: GitHub.