{"record":{"id":"1bace2712b9d93ea","repo":"crewAIInc/crewAI","slug":"error-e","errorCode":null,"errorMessage":"Error: {e}","messagePattern":"Error: (.+?)","errorType":"exception","errorClass":"SystemExit","httpStatus":null,"severity":"error","filePath":"lib/cli/src/crewai_cli/cli.py","lineNumber":122,"sourceCode":"def crewai() -> None:\n    \"\"\"Top-level command group for crewai.\"\"\"\n\n\n@crewai.command(\n    name=\"uv\",\n    context_settings={\"ignore_unknown_options\": True},\n)\n@click.argument(\"uv_args\", nargs=-1, type=click.UNPROCESSED)\ndef uv(uv_args: tuple[str, ...]) -> None:\n    \"\"\"A wrapper around uv commands that adds custom tool authentication through env vars.\"\"\"\n    try:\n        read_toml()\n    except FileNotFoundError as e:\n        raise SystemExit(\n            \"Error. A valid pyproject.toml file is required. Check that a valid pyproject.toml file exists in the current directory.\"\n        ) from e\n    except Exception as e:\n        raise SystemExit(f\"Error: {e}\") from e\n\n    env = build_env_with_all_tool_credentials()\n\n    try:\n        subprocess.run(  # noqa: S603\n            [\"uv\", *uv_args],  # noqa: S607\n            capture_output=False,\n            env=env,\n            text=True,\n            check=True,\n        )\n    except subprocess.CalledProcessError as e:\n        click.secho(f\"uv command failed with exit code {e.returncode}\", fg=\"red\")\n        raise SystemExit(e.returncode) from e\n\n\n@crewai.command()\n@click.argument(","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/cli/src/crewai_cli/cli.py#L104-L140","documentation":"Raised as HTTP 401 when the OAuth2 introspection endpoint (RFC 7662) successfully responded but reported the token as inactive (\"active\": false or missing). This means the token is expired, revoked, malformed, or was issued to a different IdP/client, so the A2A server refuses the request.","triggerScenarios":"Presenting a Bearer token to an A2A endpoint guarded by OAuth2ServerAuth(introspection_url=...) when: the access token has expired; the token was revoked at the IdP (logout, admin revocation); the token belongs to a different authorization server; or the token string is corrupt so the IdP cannot recognize it. Path: _authenticate_introspection -> introspection_result.get('active', False) is falsy (server_schemes.py:621-629).","commonSituations":"Long-running agent conversations outliving the access-token TTL; cached tokens reused after user logout; environment switch (token from staging IdP sent to production server); clock skew making the IdP consider the token expired.","solutions":["Obtain a fresh access token from the IdP and retry the request","If tokens expire frequently, request a longer TTL or implement refresh-token rotation in the client auth scheme","Verify the token was issued by the same IdP/client that the server introspects against","Decode the token (jwt.io or jwt.decode without verification) to check exp/iat and confirm it is not already expired at issue time"],"exampleFix":"# before\nauth = BearerTokenAuth(token=os.environ[\"ACCESS_TOKEN\"])  # token expired hours ago\n\n# after\nauth = BearerTokenAuth(token=fetch_fresh_access_token())  # client-credentials or refresh flow\nawait client.invoke(agent_card, request, auth=auth)","handlingStrategy":"retry","validationCode":"import time\nfrom jwt import decode  # PyJWT, unverified peek\n\ndef token_still_valid(token: str, skew: int = 30) -> bool:\n    try:\n        claims = decode(token, options={\"verify_signature\": False})\n        exp = claims.get(\"exp\")\n        return exp is None or exp - skew > time.time()\n    except Exception:\n        return False","typeGuard":null,"tryCatchPattern":"from fastapi import HTTPException\n\ntry:\n    user = await scheme.authenticate(request)\nexcept HTTPException as e:\n    if e.status_code == 401 and e.detail == \"Token is not active\":\n        token = await refresh_access_token()  # refresh flow\n        retry with new token\n    else:\n        raise","preventionTips":["Refresh access tokens before expiry using the exp claim, with clock-skew margin","Use the retry_on_401 helper in crewai.a2a.auth.utils which re-authenticates and retries once on 401","Keep tokens for one environment only; never reuse tokens across IdPs","In tests, mint short-lived tokens so suites don't fail on stale fixtures"],"tags":["oauth2","authentication","a2a","token-expired","http-401"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}