{"record":{"id":"8f012a050d11b727","repo":"paperclipai/paperclip","slug":"eval-session-provider-driver-mismatch","errorCode":null,"errorMessage":"eval-session provider/driver mismatch","messagePattern":"eval-session provider/driver mismatch","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/cli/eval-session-contract.ts","lineNumber":234,"sourceCode":"  if (input.schema !== EVAL_SESSION_REQUEST_SCHEMA) {\n    throw new Error(\"unsupported request schema\");\n  }\n  const providerValue = input.provider ?? \"codex\";\n  if (\n    providerValue !== \"codex\" &&\n    providerValue !== \"opencode\" &&\n    providerValue !== \"claude_managed\" &&\n    providerValue !== \"aws_agentcore\" &&\n    providerValue !== \"acpx\"\n  ) {\n    throw new Error(\n      \"eval-session provider is unsupported by CapabilityLiveSessionService\",\n    );\n  }\n  const provider = providerValue;\n  const driver = expectedEvalSessionDriver(provider);\n  if (input.driver !== undefined && input.driver !== driver) {\n    throw new Error(\"eval-session provider/driver mismatch\");\n  }\n  // The original Evalbook v1 producer serialized absent provider-specific\n  // options as JSON null. Preserve compatibility with those immutable request\n  // artifacts while continuing to reject non-null values for the wrong lane.\n  const acpxAgent = input.acpxAgent === null ? undefined : input.acpxAgent;\n  if (acpxAgent === \"pi\") throw new Error(\"The Pi ACPX profile is not available\");\n  if (\n    acpxAgent !== undefined &&\n    acpxAgent !== \"codex\" &&\n    acpxAgent !== \"claude\"\n  ) {\n    throw new Error(\"eval-session acpxAgent must be codex or claude\");\n  }\n  if (provider !== \"acpx\" && acpxAgent !== undefined) {\n    throw new Error(\"eval-session acpxAgent requires provider acpx\");\n  }\n  const managedProfileInput = input.managedProfile === null\n    ? undefined","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/cli/eval-session-contract.ts#L216-L252","documentation":"parseEvalSessionRequest validates that the eval-session request's optional 'driver' field matches the driver implied by the chosen 'provider'. Each provider maps to exactly one driver (codex -> codex_app_server, opencode -> opencode_server, claude_managed -> claude_managed_agents_api, aws_agentcore -> aws_agentcore_harness_api, acpx -> acpx_runtime). This fail-closed check exists because the request crosses an executable/CLI boundary, so a mismatched driver/provider pair would silently target the wrong runtime.","triggerScenarios":"Calling parseEvalSessionRequest (via the request entry point) with a request object where input.driver is defined and does not equal expectedEvalSessionDriver(provider), e.g. {provider:'opencode', driver:'codex_app_server'} or a stale/hand-edited request file where driver was not updated after changing provider.","commonSituations":"Hand-editing or templating eval-session request JSON and changing provider but forgetting to update driver; reusing a request file from a previous run against a different provider; a generator script hardcoding driver values; typos in the driver constant.","solutions":["Remove the explicit 'driver' field from the request and let the contract derive it from 'provider' (driver is optional).","Set driver to the exact value returned by expectedEvalSessionDriver(provider): codex->'codex_app_server', opencode->'opencode_server', claude_managed->'claude_managed_agents_api', aws_agentcore->'aws_agentcore_harness_api', acpx->'acpx_runtime'.","Regenerate the request from the current schema/version instead of reusing an old request file.","Call expectedEvalSessionDriver(provider) in your generator and assign its result to driver."],"exampleFix":"// before\nconst request = { schema, provider: \"opencode\", driver: \"codex_app_server\", ... };\n// after\nimport { expectedEvalSessionDriver } from \"./eval-session-contract.js\";\nconst request = { schema, provider: \"opencode\", driver: expectedEvalSessionDriver(\"opencode\"), ... };\n// or simply omit driver:\nconst request = { schema, provider: \"opencode\", ... };","handlingStrategy":"validation","validationCode":"import { expectedEvalSessionDriver } from \"./eval-session-contract.js\";\nfunction assertDriverMatches(request: { provider?: string; driver?: string }): void {\n  const provider = request.provider ?? \"codex\";\n  const allowed = [\"codex\", \"opencode\", \"claude_managed\", \"aws_agentcore\", \"acpx\"] as const;\n  if (!(allowed as readonly string[]).includes(provider)) {\n    throw new Error(`unsupported provider: ${provider}`);\n  }\n  const expected = expectedEvalSessionDriver(provider as typeof allowed[number]);\n  if (request.driver !== undefined && request.driver !== expected) {\n    throw new Error(`driver ${request.driver} != expected ${expected} for provider ${provider}`);\n  }\n}","typeGuard":"const DRIVER_BY_PROVIDER = {\n  codex: \"codex_app_server\",\n  opencode: \"opencode_server\",\n  claude_managed: \"claude_managed_agents_api\",\n  aws_agentcore: \"aws_agentcore_harness_api\",\n  acpx: \"acpx_runtime\",\n} as const;\nfunction hasValidDriver(r: { provider?: string; driver?: string }): boolean {\n  const p = (r.provider ?? \"codex\") as keyof typeof DRIVER_BY_PROVIDER;\n  return r.driver === undefined || r.driver === DRIVER_BY_PROVIDER[p];\n}","tryCatchPattern":"try {\n  const parsed = parseEvalSessionRequest(raw);\n} catch (err) {\n  if (err instanceof Error && err.message === \"eval-session provider/driver mismatch\") {\n    console.error(`Bad driver for provider ${raw.provider}: drop 'driver' or use expectedEvalSessionDriver(provider)`);\n  } else throw err;\n}","preventionTips":["Omit the optional 'driver' field and let the contract derive it from 'provider'.","If you must set driver, always compute it via expectedEvalSessionDriver(provider) instead of hardcoding strings.","Don't hand-edit generated request files; regenerate them after changing provider.","Add a pre-submit lint that asserts driver === expectedEvalSessionDriver(provider)."],"tags":["validation","contract","config"],"backgroundTag":"provider-driver-mismatch","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}