{"record":{"id":"ce82de486eeba3a5","repo":"mvanhorn/last30days-skill","slug":"openai-selected-but-no-valid-openai-auth-is-config","errorCode":null,"errorMessage":"OpenAI selected but no valid OpenAI auth is configured.","messagePattern":"OpenAI selected but no valid OpenAI auth is configured\\.","errorType":"validation","errorClass":"RuntimeError","httpStatus":null,"severity":"critical","filePath":"skills/last30days/scripts/lib/providers.py","lineNumber":278,"sourceCode":"            ), None\n\n    planner_model, rerank_model = _resolve_model_pins(config, depth, provider_name)\n\n    if provider_name == \"gemini\":\n        if not google_key:\n            raise RuntimeError(\"Gemini selected but no Google API key is configured.\")\n        runtime = schema.ProviderRuntime(\n            reasoning_provider=\"gemini\",\n            planner_model=planner_model,\n            rerank_model=rerank_model,\n    \n            x_search_backend=_resolve_x_backend(config),\n        )\n        return runtime, GeminiClient(google_key)\n\n    if provider_name == \"openai\":\n        if not openai_token or config.get(\"OPENAI_AUTH_STATUS\") != env.AUTH_STATUS_OK:\n            raise RuntimeError(\"OpenAI selected but no valid OpenAI auth is configured.\")\n        runtime = schema.ProviderRuntime(\n            reasoning_provider=\"openai\",\n            planner_model=planner_model,\n            rerank_model=rerank_model,\n    \n            x_search_backend=_resolve_x_backend(config),\n        )\n        return runtime, OpenAIClient(\n            openai_token\n        )\n\n    if provider_name == \"xai\":\n        if not xai_key:\n            raise RuntimeError(\"xAI selected but XAI_API_KEY is not configured.\")\n        runtime = schema.ProviderRuntime(\n            reasoning_provider=\"xai\",\n            planner_model=planner_model,\n            rerank_model=rerank_model,","sourceCodeStart":260,"sourceCodeEnd":296,"githubUrl":"https://github.com/mvanhorn/last30days-skill/blob/c7460f6114449ddfe6ea3fc2f23c3d910c0e740c/skills/last30days/scripts/lib/providers.py#L260-L296","documentation":"RuntimeError raised in resolve_runtime for provider 'openai' when either the OpenAI token is missing or the OPENAI_AUTH_STATUS config entry is not the AUTH_STATUS_OK sentinel. The double gate means a merely-present token is insufficient - auth must have been validated by the env/onboarding layer.","triggerScenarios":"LAST30DAYS_REASONING_PROVIDER=openai with OPENAI_API_KEY absent, or with the key present but OPENAI_AUTH_STATUS not marked OK (e.g. token failed validation during onboarding, or status was never written).","commonSituations":"Expired or revoked OpenAI tokens where auth validation failed but the raw key lingers in env; partial onboarding that saved the key but not the status entry; env files copied between machines with mismatched status keys.","solutions":["Re-run the setup/auth flow so the OpenAI token is validated and OPENAI_AUTH_STATUS is set to OK","Replace an expired OPENAI_API_KEY with a working one and re-validate","Verify both the token variable and the auth-status variable are loaded into the config dict, not just the shell"],"exampleFix":"# before\nOPENAI_API_KEY=sk-expired...\n# OPENAI_AUTH_STATUS unset -> raise\n\n# after\nOPENAI_API_KEY=sk-valid...\nOPENAI_AUTH_STATUS=ok  # written by validated onboarding","handlingStrategy":"validation","validationCode":"def openai_ready(config: dict) -> bool:\n    return bool(\n        config.get(\"OPENAI_API_KEY\")\n        and config.get(\"OPENAI_AUTH_STATUS\") == \"ok\"\n    )","typeGuard":"def openai_auth_ok(config: dict) -> bool:\n    # both gates from providers.py: token present AND status validated\n    return bool(config.get(\"OPENAI_API_KEY\")) and config.get(\"OPENAI_AUTH_STATUS\") is not None","tryCatchPattern":"try:\n    runtime, client = resolve_runtime(config, depth)\nexcept RuntimeError as e:\n    if \"no valid OpenAI auth\" in str(e):\n        rerun_onboarding_auth()  # revalidates token and rewrites status","preventionTips":["Re-run auth onboarding after rotating the OpenAI key so the status entry is rewritten","Never assume a present key equals a validated key - the status gate exists","Preflight both OPENAI_API_KEY and OPENAI_AUTH_STATUS in CI job setup"],"tags":["providers","openai","auth","credentials"],"backgroundTag":null,"analyzedSha":"c7460f6114449ddfe6ea3fc2f23c3d910c0e740c","analyzedAt":"2026-08-15T03:34:49.540Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}