{"record":{"id":"9ab56173a4a823a2","repo":"crewAIInc/crewAI","slug":"oidc-not-initialized","errorCode":null,"errorMessage":"OIDC not initialized","messagePattern":"OIDC not initialized","errorType":"http","errorClass":"HTTPException","httpStatus":500,"severity":"critical","filePath":"lib/crewai/src/crewai/a2a/auth/server_schemes.py","lineNumber":275,"sourceCode":"            else f\"{str(self.issuer).rstrip('/')}/.well-known/jwks.json\"\n        )\n        self._jwk_client = PyJWKClient(jwks_url, lifespan=self.jwks_cache_ttl)\n        return self\n\n    async def authenticate(self, token: str) -> AuthenticatedUser:\n        \"\"\"Authenticate using OIDC JWT validation.\n\n        Args:\n            token: The JWT to authenticate.\n\n        Returns:\n            AuthenticatedUser on successful authentication.\n\n        Raises:\n            HTTPException: If authentication fails.\n        \"\"\"\n        if self._jwk_client is None:\n            raise HTTPException(\n                status_code=HTTP_500_INTERNAL_SERVER_ERROR,\n                detail=\"OIDC not initialized\",\n            )\n\n        try:\n            signing_key = self._jwk_client.get_signing_key_from_jwt(token)\n\n            claims = jwt.decode(\n                token,\n                signing_key.key,\n                algorithms=self.algorithms,\n                audience=self.audience,\n                issuer=str(self.issuer).rstrip(\"/\"),\n                leeway=self.clock_skew_seconds,\n                options={\n                    \"require\": self.required_claims,\n                },\n            )","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai/src/crewai/a2a/auth/server_schemes.py#L257-L293","documentation":"Raised by OIDCAuth.authenticate() when the private _jwk_client attribute is None, meaning the scheme was never initialized with a JWKS endpoint. It returns HTTP 500 because it is an internal state error: the scheme object exists but cannot perform validation. Under normal construction the model validator builds the PyJWKClient from jwks_url, so reaching this branch implies the validator was skipped or the object was mutated.","triggerScenarios":"Calling authenticate() on an OIDCAuth instance constructed without a usable jwks_url (or after manually clearing _jwk_client); bypassing pydantic validation via model_construct(); or an OIDC provider that exposes no JWKS URL so initialization silently left the client as None.","commonSituations":"Building the scheme from a partial dict that omitted jwks_url; using model_construct() or object reuse/copying that skips model_validator(mode='after'); a discovery step that failed upstream and left a half-initialized scheme.","solutions":["Construct OIDCAuth with a valid jwks_url so the model validator creates the PyJWKClient: OIDCAuth(jwks_url='https://idp/.well-known/jwks.json', ...).","Never instantiate the scheme with model_construct(); let pydantic run validators.","Add a startup assertion that getattr(scheme, '_jwk_client', None) is not None before serving traffic.","If configuring from discovery documents, fail startup when the discovered jwks_uri is missing."],"exampleFix":"# before\nscheme = OIDCAuth.model_construct(issuer=\"https://idp\")  # validator skipped, _jwk_client=None\n\n# after\nscheme = OIDCAuth(\n    issuer=\"https://idp\",\n    jwks_url=\"https://idp/.well-known/jwks.json\",\n    audience=\"my-audience\",\n)","handlingStrategy":"validation","validationCode":"from crewai.a2a.auth.server_schemes import OIDCAuth\n\nscheme = OIDCAuth(\n    issuer=\"https://idp\", jwks_url=\"https://idp/.well-known/jwks.json\", audience=\"api\"\n)\n# smoke check before serving traffic\nassert scheme._jwk_client is not None, \"OIDCAuth initialized without a JWKS client\"","typeGuard":"def is_initialized_oidc(scheme: ServerAuthScheme) -> bool:\n    \"\"\"True when the scheme is an OIDCAuth with a live JWKS client.\"\"\"\n    return (\n        type(scheme).__name__ == \"OIDCAuth\"\n        and getattr(scheme, \"_jwk_client\", None) is not None\n    )","tryCatchPattern":null,"preventionTips":["Always construct schemes via normal __init__/model_validate so validators run.","Never use model_construct() for auth schemes.","Smoke-test authentication once at startup with a real or dummy token."],"tags":["a2a","oidc","jwks","initialization","http-500"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}