{"record":{"id":"cfc1ba6143299700","repo":"JuliusBrussee/caveman","slug":"cache-replay-openai-api-key-unavailable","errorCode":null,"errorMessage":"cache-replay: OPENAI_API_KEY unavailable","messagePattern":"cache-replay: OPENAI_API_KEY unavailable","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"cacheengine/cmd/cache-replay/main.go","lineNumber":377,"sourceCode":"\tif err != nil {\n\t\treturn nil, \"\", err\n\t}\n\tif limited.N <= 0 {\n\t\treturn nil, \"\", fmt.Errorf(\"cache-replay: trace exceeds %d bytes\", maxBytes)\n\t}\n\treturn records, hex.EncodeToString(hash.Sum(nil)), nil\n}\n\nfunc validateProviderCredentials(records []cachebench.TraceRecord) error {\n\tproviders := map[string]bool{}\n\tfor _, record := range records {\n\t\tproviders[record.Provider] = true\n\t}\n\tfor provider := range providers {\n\t\tswitch provider {\n\t\tcase \"openai\":\n\t\t\tif os.Getenv(\"OPENAI_API_KEY\") == \"\" {\n\t\t\t\treturn errors.New(\"cache-replay: OPENAI_API_KEY unavailable\")\n\t\t\t}\n\t\tcase \"anthropic\":\n\t\t\tif os.Getenv(\"ANTHROPIC_API_KEY\") == \"\" {\n\t\t\t\treturn errors.New(\"cache-replay: ANTHROPIC_API_KEY unavailable\")\n\t\t\t}\n\t\tcase \"gemini\":\n\t\t\tif os.Getenv(\"GEMINI_API_KEY\") == \"\" {\n\t\t\t\treturn errors.New(\"cache-replay: GEMINI_API_KEY unavailable\")\n\t\t\t}\n\t\tcase \"bedrock\":\n\t\t\tif os.Getenv(\"AWS_BEARER_TOKEN_BEDROCK\") == \"\" && (os.Getenv(\"AWS_ACCESS_KEY_ID\") == \"\" || os.Getenv(\"AWS_SECRET_ACCESS_KEY\") == \"\") {\n\t\t\t\treturn errors.New(\"cache-replay: Bedrock bearer token or AWS access credentials unavailable\")\n\t\t\t}\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"cache-replay: unsupported provider %q\", provider)\n\t\t}\n\t}\n\treturn nil","sourceCodeStart":359,"sourceCodeEnd":395,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/cacheengine/cmd/cache-replay/main.go#L359-L395","documentation":"Returned by validateProviderCredentials when the trace contains openai requests but the OPENAI_API_KEY environment variable is empty in the cache-replay process. Credential presence is checked per distinct provider found in the trace before any live request is made, so replay against OpenAI fails fast instead of 401-ing mid-run.","triggerScenarios":"Running cache-replay -execute on a trace with provider \"openai\" records without exporting OPENAI_API_KEY. The key must exist in the tool's own environment; note that verifier subprocesses get a scrubbed env and never see provider keys.","commonSituations":"CI job secrets not mapped to the env var name; exporting the key in a different shell than the one running the tool; .env file loaded by a wrapper but not by the direct invocation; trace recorded across multiple providers but only some keys provisioned.","solutions":["Export OPENAI_API_KEY in the environment of the cache-replay process (export OPENAI_API_KEY=... or env-file mechanism)","Confirm the trace actually needs OpenAI: if not, filter the trace to the providers you have keys for","In CI, add the secret under the exact name OPENAI_API_KEY"],"exampleFix":"# before\ncache-replay -execute ...\n\n# after\nexport OPENAI_API_KEY=\"$OPENAI_KEY_FROM_SECRET_MANAGER\"\ncache-replay -execute ...","handlingStrategy":"validation","validationCode":"providers := map[string]bool{}\nfor _, r := range records {\n\tproviders[r.Provider] = true\n}\nif providers[\"openai\"] && os.Getenv(\"OPENAI_API_KEY\") == \"\" {\n\treturn errors.New(\"set OPENAI_API_KEY before live replay\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run a startup credential preflight that maps each trace provider to its required env var name","In CI, name secrets exactly OPENAI_API_KEY/ANTHROPIC_API_KEY/GEMINI_API_KEY/AWS_* so the tool's checks pass"],"tags":["go","credentials","environment","cli"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}