Skip to content

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

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

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