BerriAI/litellm · error · Exception

Access denied to prompt version

Error message

Access denied to prompt version '{prompt_version_id}'. Check your Arize Phoenix permissions.

What it means

When ArizePhoenixClient.get_prompt_version receives HTTP 403 from the Phoenix API, it converts the httpx error into this explicit Exception: the API key authenticated successfully but the token's role/workspace lacks permission to read that prompt version. Access control on Phoenix Cloud is per-workspace, so a valid key for the wrong workspace yields 403.

Solutions

  1. In the Phoenix UI, open the prompt and confirm which workspace it belongs to; regenerate/use an API key from that exact workspace
  2. Grant the key's role read access to prompts, or switch to a key with member/admin role for that workspace
  3. Verify independently with curl: `curl -H "Authorization: Bearer $PHOENIX_API_KEY" <api_base>/prompt_versions/<id>` — 403 confirms permissions, 401 would confirm auth
Defensive patterns

Strategy: try-catch

Validate before calling

# Pre-flight the exact read before wiring the prompt into serving paths
import httpx, os

resp = httpx.get(
    f"{api_base}/prompt_versions/{prompt_version_id}",
    headers={"Authorization": f"Bearer {os.environ['PHOENIX_API_KEY']}"},
    timeout=5,
)
if resp.status_code == 403:
    raise SystemExit("Key lacks access to this prompt — check workspace/role in Phoenix")

Try / catch

try:
    manager.compile(prompt_id=prompt_id, prompt_variables=vars)
except Exception as e:
    msg = str(e)
    if "Access denied" in msg:
        # permissions issue: fail loudly at config time, do not retry — fix workspace/role
        raise PermissionError(f"Phoenix key cannot read {prompt_id}: wrong workspace or role") from e
    raise

Prevention

When it happens

Trigger: Loading a prompt whose prompt_version_id belongs to a different Phoenix workspace or a private prompt your service account cannot read; using a viewer-role API key against a restricted prompt; cross-org access on Phoenix Cloud.

Common situations: Key generated in workspace A while the prompt lives in workspace B; rotating to a least-privilege service key that lacks prompt read scope; prompting against an org's private prompt set with a personal key from another org.

Understand the failure class

Related errors


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/3ed87c234785ee8a. Report an issue: GitHub.

Appendix: source

Thrown at litellm/integrations/arize/arize_phoenix_client.py:84

        safe_id: Final = _sanitize_id(prompt_version_id)
        url: Final = f"{self.api_base}/v1/prompt_versions/{safe_id}"

        try:
            # Use the underlying httpx client directly to avoid query param extraction
            response = self.http_handler.get(url, headers=self.headers)
            response.raise_for_status()

            data: Final = response.json()
            return data.get("data")

        except Exception as e:
            # Check if it's an HTTP error
            response = getattr(e, "response", None)
            if response is not None and hasattr(response, "status_code"):
                if response.status_code == 404:
                    return None
                elif response.status_code == 403:
                    raise Exception(
                        f"Access denied to prompt version '{prompt_version_id}'. Check your Arize Phoenix permissions."
                    )
                elif response.status_code == 401:
                    raise Exception("Authentication failed. Check your Arize Phoenix API key and permissions.")
                else:
                    raise Exception(f"Failed to fetch prompt version '{prompt_version_id}': {e}")
            else:
                raise Exception(f"Error fetching prompt version '{prompt_version_id}': {e}")

    def test_connection(self) -> bool:
        """
        Test the connection to the Arize Phoenix API.

        Returns:
            True if connection is successful, False otherwise
        """
        try:
            # Try to access the prompt_versions endpoint to test connection

View on GitHub (pinned to 77b7c6c40c)