{"record":{"id":"480c0a1024896b39","repo":"Significant-Gravitas/AutoGPT","slug":"no-api-key-in-request","errorCode":null,"errorMessage":"No API key in request","messagePattern":"No API key in request","errorType":"http","errorClass":"HTTPException","httpStatus":401,"severity":"error","filePath":"autogpt_platform/backend/backend/api/utils/api_key_auth.py","lineNumber":86,"sourceCode":"            Callable[[str], Any] | Callable[[str], Awaitable[Any]]\n        ] = None,\n        status_if_missing: int = HTTP_401_UNAUTHORIZED,\n        message_if_invalid: str = \"Invalid API key\",\n    ):\n        super().__init__(\n            name=header_name,\n            scheme_name=f\"{__class__.__name__}-{header_name}\",\n            auto_error=False,\n        )\n        self.expected_token = expected_token\n        self.custom_validator = validator\n        self.status_if_missing = status_if_missing\n        self.message_if_invalid = message_if_invalid\n\n    async def __call__(self, request: Request) -> Any:\n        api_key = await super().__call__(request)\n        if api_key is None:\n            raise HTTPException(\n                status_code=self.status_if_missing, detail=\"No API key in request\"\n            )\n\n        # Use custom validation if provided, otherwise use default equality check\n        validator = self.custom_validator or self.default_validator\n        result = (\n            await validator(api_key)\n            if inspect.iscoroutinefunction(validator)\n            else validator(api_key)\n        )\n\n        if not result:\n            raise HTTPException(\n                status_code=self.status_if_missing, detail=self.message_if_invalid\n            )\n\n        # Store validation result in request state if it's not just a boolean\n        if result is not True:","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/Significant-Gravitas/AutoGPT/blob/9c8bb5550f446ba5d3046b78896578742495b3cf/autogpt_platform/backend/backend/api/utils/api_key_auth.py#L68-L104","documentation":"APIKeyAuthenticator.__call__ raises HTTPException with status_if_missing (default HTTP_401_UNAUTHORIZED, configurable per authenticator instance — e.g. 403 where 401 would break browser flows) when the configured header (e.g. X-API-Key) is absent from the request. The underlying fastapi.security APIKeyHeader was constructed with auto_error=False so this custom, configurable-status error is raised instead. This is the 'missing header' branch, distinct from the 'present but invalid' branch that uses message_if_invalid.","triggerScenarios":"Calling any endpoint protected by an APIKeyAuthenticator without the expected header — e.g. missing X-API-Key on external-api routes, or a webhook adapter route that requires a token header that wasn't sent.","commonSituations":"Clients sending the key as a Bearer Authorization header instead of the custom header name; typos in the header name (x-api-key casing is fine, but 'apikey' is not); proxies (nginx, CORS preflight handling) stripping custom headers; integration code that only sets the header on some requests.","solutions":["Send the exact header name the authenticator was constructed with (see its header_name), e.g. `X-API-Key: <key>` on every request.","Verify intermediaries (proxies, API gateways, fetch wrappers) forward custom headers and handle CORS preflight for them.","Distinguish this from an invalid key: missing header → 'No API key in request'; wrong value → the authenticator's message_if_invalid.","Centralize header injection in one HTTP client wrapper instead of per-call."],"exampleFix":"# before\nresp = requests.get(url, headers={'Authorization': f'Bearer {key}'})\n# after\nresp = requests.get(url, headers={'X-API-Key': key})","handlingStrategy":"validation","validationCode":"function withApiKey(headers: Record<string, string> = {}): Record<string, string> {\n  if (!API_KEY) throw new Error('API key not configured');\n  return { ...headers, 'X-API-Key': API_KEY };\n}\nawait fetch(url, { headers: withApiKey() });","typeGuard":"function hasApiKeyHeader(headers: Headers, name = 'X-API-Key'): boolean {\n  return Boolean(headers.get(name));\n}","tryCatchPattern":"try {\n  return await client.get(path, { headers: { 'X-API-Key': apiKey } });\n} catch (e) {\n  if (e.status === 401 && e.detail === 'No API key in request') {\n    throw new Error(`Missing ${HEADER_NAME} header — check client config`);\n  }\n  throw e;\n}","preventionTips":["Set the custom header in one shared HTTP client wrapper used for every call.","Confirm the exact header name the authenticator expects (header_name), not Bearer auth.","Ensure proxies/gateways forward custom headers and that CORS allows them."],"tags":["http-401","authentication","api-key","headers"],"backgroundTag":null,"analyzedSha":"9c8bb5550f446ba5d3046b78896578742495b3cf","analyzedAt":"2026-08-14T17:17:21.957Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}