Skip to content

[Bug] Vertex replay session id uses promptCacheKey, which is shared across conversations #1312

Closed

Description

@lidge-jun

Client or integration

Codex CLI

Area

Provider adapter

Summary

vertexReplaySessionId() (src/adapters/google.ts:56) keys the Vertex thought-signature replay namespace on parsed.options.promptCacheKey, under a comment that says it does something else:

/** Prefer Codex's stable opaque thread key; retain the existing deterministic fallback for clients
 * that omit it. ... */
function vertexReplaySessionId(parsed: OcxParsedRequest): string {
  const promptCacheKey = parsed.options.promptCacheKey?.trim();
  return promptCacheKey || antigravitySessionId(parsed);
}

promptCacheKey is not a thread key. It is the client-supplied Responses prompt_cache_key, accepted as any string (src/responses/schema.ts, copied at src/responses/parser.ts:661), and this repository elsewhere treats it as explicitly shared across conversations:

  • src/adapters/cursor/request-builder.ts:227 warns against using a shared prompt_cache_key as a conversation id;
  • Claude Desktop cache cohorts are marked as shared in src/server/responses/core.ts:620 and src/server/claude-messages.ts:701.

So two distinct conversations in the same cache cohort share a Vertex replay namespace, and any client can choose the value.

Relationship to #1297

This is the same class of defect #1297 reported for the Cloud Code Assist path, on a different anchor. #1311 fixed the CCA side by anchoring on _clientThreadId and deliberately not on promptCacheKey; it left this one alone rather than bundling an unrelated path into that fix.

Worth recording how it surfaced: while fixing #1297 I found this function and read its comment as the correct pattern to copy. It is not — the comment describes the right anchor and the code uses a different one. Anyone reading google.ts for guidance will make the same mistake.

Severity

Lower than #1297, and the two failure modes differ in kind:

Sharing is partly mitigated the same way the original CCA comment argued: the replay cache keys signatures on functionCall identity (name + args), so a shared namespace does not by itself misattribute a signature. That mitigation is real but it is not a reason for the anchor to be wrong, and it does not cover a client that chooses the value deliberately.

Suggested fix

Mirror #1311: prefer parsed._clientThreadId (populated from x-codex-parent-thread-id at src/server/responses/core.ts:1413), fall back to the existing deterministic id. Unlike the CCA case this value never leaves the process — it scopes a local replay store rather than going on the wire — so the change carries no provider-visible risk.

If promptCacheKey is kept for some reason I have not seen, the comment should at least stop claiming it is a thread key.

Version

dev at b5d44a534.

Operating system

Not platform-specific.

Activity

  1. github-actions commented on Aug 8, 2026

    @github-actions
    Contributor

    Automated translation bookkeeping — detected language: English.

  2. added
    providerProvider adapters, OpenAI-compat presets, upstream API quirks
    on Aug 8, 2026
  3. added
    bugSomething isn't working
    platformOS/service/tray/ACL (Windows-heavy, not Windows-only)
    cliCLI, config inject, packaging flags
    on Aug 9, 2026
  4. Ingwannu commented on Aug 9, 2026

    @Ingwannu
    Owner

    Confirmed on current dev: vertexReplaySessionId still prefers promptCacheKey even though that value is a cache cohort and can be shared across conversations. The issue is real and the proposed boundary is correct.\n\nI will mirror the #1311 Cloud Code Assist fix for the local Vertex replay namespace: prefer a nonblank _clientThreadId, fall back to the existing deterministic antigravitySessionId when no thread header exists, and stop using promptCacheKey for replay identity. No identifier will be sent upstream; this only scopes the local thought-signature store.\n\nRegression coverage will prove that two conversations with the same prompt cache key but different client thread ids do not share a replay namespace, while threadless clients retain the deterministic fallback. I will link a separate dev-targeted PR after validation rather than bundle it with the unrelated DeepSeek ordering fix.

  5. Ingwannu commented on Aug 9, 2026

    @Ingwannu
    Owner

    Implemented the thread-isolation fix in ready-for-review PR #1335.

    The replay namespace now prefers Codex's stable client thread ID instead of promptCacheKey, so two threads sharing a cache cohort cannot replay each other's Vertex thought signatures. Threadless clients retain the existing deterministic fallback.

    Validation on the exact PR head:

    • TypeScript typecheck passed.
    • 227 focused Google/Vertex/Antigravity tests passed with 0 failures.
    • All required GitHub CI checks passed on Linux, macOS, and Windows-related smoke jobs.
    • git diff --check passed.

    Review remains requested from @lidge-jun and @Wibias. I will leave the issue open until the fix is independently approved and lands on dev.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingcliCLI, config inject, packaging flagsplatformOS/service/tray/ACL (Windows-heavy, not Windows-only)providerProvider adapters, OpenAI-compat presets, upstream API quirks

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions