{"record":{"id":"8dd3102dd573d4b8","repo":"paperclipai/paperclip","slug":"request-session-provider-must-match-request-provid","errorCode":null,"errorMessage":"request.session.provider must match request.provider","messagePattern":"request\\.session\\.provider must match request\\.provider","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/cli/eval-session-contract.ts","lineNumber":301,"sourceCode":"    throw new Error(\"request.runnerd.sha256 must be a SHA-256 digest\");\n  }\n  const limits = object(input.limits, \"request.limits\");\n  const sessionInput = object(input.session, \"request.session\");\n  const session = sessionInput as unknown as CreateCapabilityLiveSessionInput;\n  const model = text(input.model, \"request.model\");\n  if (provider === \"claude_managed\" && model !== \"claude-sonnet-5\") {\n    throw new Error(\"Claude Managed evals require exact model claude-sonnet-5\");\n  }\n  if (\n    provider === \"aws_agentcore\" &&\n    model !== \"global.anthropic.claude-sonnet-4-6\"\n  ) {\n    throw new Error(\n      \"AWS AgentCore evals require exact model global.anthropic.claude-sonnet-4-6\",\n    );\n  }\n  if (sessionInput.provider !== undefined && sessionInput.provider !== provider) {\n    throw new Error(\"request.session.provider must match request.provider\");\n  }\n  if (\n    session.requestedModel !== undefined &&\n    session.requestedModel !== model\n  ) {\n    throw new Error(\"request.session.requestedModel must match request.model\");\n  }\n  if (session.acpxAgent === \"pi\") {\n    throw new Error(\"The Pi ACPX profile is not available\");\n  }\n\n  return {\n    schema: EVAL_SESSION_REQUEST_SCHEMA,\n    attemptId: text(input.attemptId, \"request.attemptId\"),\n    prompt: text(input.prompt, \"request.prompt\"),\n    model,\n    provider,\n    driver,","sourceCodeStart":283,"sourceCodeEnd":319,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/cli/eval-session-contract.ts#L283-L319","documentation":"parseEvalSessionRequest requires that when request.session.provider is supplied it must exactly equal the top-level request.provider (eval-session-contract.ts:291-293). The session block is the CreateCapabilityLiveSessionInput forwarded to CapabilityLiveSessionService, and a mismatch would mean the live session runs on a different agent provider than the eval request declares. The guard is fail-closed: omit session.provider to inherit the top-level value, or keep the two identical.","triggerScenarios":"Submitting an eval-session request where request.provider is e.g. 'codex' but request.session.provider is 'opencode', 'claude_managed', 'acpx', or any other string (including undefined-vs-typo differences like 'claude_managed' vs 'claude-managed').","commonSituations":"Hand-editing one field of the request JSON and not the nested session block; copying a session object from a request built for a different provider; template/stale request files after a provider migration.","solutions":["Set request.session.provider to the same value as request.provider, or delete request.session.provider entirely so it defaults to the top-level provider.","Search the request JSON for \"session\" and verify every mirrored field (provider, requestedModel) matches the top-level request fields.","Regenerate the request from the tooling that pairs provider and session together instead of editing by hand.","If this happens programmatically, fix the code that builds CreateCapabilityLiveSessionInput to derive session.provider from the same variable used for request.provider."],"exampleFix":"// before\n{\n  \"provider\": \"codex\",\n  \"session\": { \"provider\": \"opencode\", ... }\n}\n// after\n{\n  \"provider\": \"codex\",\n  \"session\": { \"provider\": \"codex\", ... }\n}\n// or simply remove session.provider to inherit it","handlingStrategy":"validation","validationCode":"function assertSessionProviderMatches(req: { provider?: string; session?: { provider?: string } }): void {\n  if (req.session?.provider !== undefined && req.session.provider !== req.provider) {\n    throw new Error(`session.provider (${req.session.provider}) != provider (${req.provider})`);\n  }\n}","typeGuard":"function hasConsistentProvider(req: { provider?: string; session?: { provider?: string } }): boolean {\n  return req.session?.provider === undefined || req.session.provider === req.provider;\n}","tryCatchPattern":"try {\n  const parsed = parseEvalSessionRequest(rawRequest);\n  // proceed\n} catch (err) {\n  if (err instanceof Error && err.message === \"request.session.provider must match request.provider\") {\n    // normalize: delete session.provider or set it from top-level provider, then retry\n  } else throw err;\n}","preventionTips":["Build the session object from the same provider variable used at the top level — never duplicate the literal.","Prefer omitting session.provider; it inherits request.provider.","Diff generated request JSONs against a checked-in golden template in CI.","After any provider migration, grep request fixtures for the old provider string."],"tags":["validation","config","consistency","evals"],"backgroundTag":"config-field-mismatch","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-02T18:44:00.616Z","contentChangedAt":"2026-09-02T18:44:00.616Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}