crewAIInc/crewAI · error · SystemExit

Error: {e}

Error message

Error: {e}

What it means

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.

Source

Thrown at lib/cli/src/crewai_cli/cli.py:122

def crewai() -> None:
    """Top-level command group for crewai."""


@crewai.command(
    name="uv",
    context_settings={"ignore_unknown_options": True},
)
@click.argument("uv_args", nargs=-1, type=click.UNPROCESSED)
def uv(uv_args: tuple[str, ...]) -> None:
    """A wrapper around uv commands that adds custom tool authentication through env vars."""
    try:
        read_toml()
    except FileNotFoundError as e:
        raise SystemExit(
            "Error. A valid pyproject.toml file is required. Check that a valid pyproject.toml file exists in the current directory."
        ) from e
    except Exception as e:
        raise SystemExit(f"Error: {e}") from e

    env = build_env_with_all_tool_credentials()

    try:
        subprocess.run(  # noqa: S603
            ["uv", *uv_args],  # noqa: S607
            capture_output=False,
            env=env,
            text=True,
            check=True,
        )
    except subprocess.CalledProcessError as e:
        click.secho(f"uv command failed with exit code {e.returncode}", fg="red")
        raise SystemExit(e.returncode) from e


@crewai.command()
@click.argument(

View on GitHub (pinned to 754d7323be)

Solutions

  1. Obtain a fresh access token from the IdP and retry the request
  2. If tokens expire frequently, request a longer TTL or implement refresh-token rotation in the client auth scheme
  3. Verify the token was issued by the same IdP/client that the server introspects against
  4. Decode the token (jwt.io or jwt.decode without verification) to check exp/iat and confirm it is not already expired at issue time

Example fix

# before
auth = BearerTokenAuth(token=os.environ["ACCESS_TOKEN"])  # token expired hours ago

# after
auth = BearerTokenAuth(token=fetch_fresh_access_token())  # client-credentials or refresh flow
await client.invoke(agent_card, request, auth=auth)
Defensive patterns

Strategy: retry

Validate before calling

import time
from jwt import decode  # PyJWT, unverified peek

def token_still_valid(token: str, skew: int = 30) -> bool:
    try:
        claims = decode(token, options={"verify_signature": False})
        exp = claims.get("exp")
        return exp is None or exp - skew > time.time()
    except Exception:
        return False

Try / catch

from fastapi import HTTPException

try:
    user = await scheme.authenticate(request)
except HTTPException as e:
    if e.status_code == 401 and e.detail == "Token is not active":
        token = await refresh_access_token()  # refresh flow
        retry with new token
    else:
        raise

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15). Data as JSON: /api/errors/1bace2712b9d93ea. Report an issue: GitHub.