BerriAI/litellm · error · HTTPException

expires_after[anchor] must be 'created_at', got '{expires_af

Error message

expires_after[anchor] must be 'created_at', got '{expires_after_anchor}'

What it means

HTTPException(400) on file upload: the expires_after[anchor] value is not the only supported anchor, 'created_at' (e.g. 'fixed_time' or a typo). Expiry is only definable relative to file creation, so any other anchor is rejected with the offending value echoed.

Source

Thrown at litellm/proxy/openai_files_endpoints/files_endpoints.py:424

                        "error": "expires_after[anchor] must be a string, not a file upload",
                    },
                )

            # Validate expires_after[seconds] is a string (not UploadFile)
            # Use positive isinstance check for proper type narrowing (matches codebase pattern)
            if not isinstance(expires_after_seconds_str, str):
                raise HTTPException(
                    status_code=400,
                    detail={
                        "error": "expires_after[seconds] must be a string, not a file upload",
                    },
                )
            # After this check, mypy knows expires_after_seconds_str is str
            expires_after_seconds_str_validated: Final[str] = expires_after_seconds_str

            # Validate anchor is "created_at"
            if expires_after_anchor != "created_at":
                raise HTTPException(
                    status_code=400,
                    detail={
                        "error": f"expires_after[anchor] must be 'created_at', got '{expires_after_anchor}'",
                    },
                )

            # Convert seconds to int
            try:
                expires_after_seconds: Final = int(expires_after_seconds_str_validated)
            except (ValueError, TypeError) as e:
                raise HTTPException(
                    status_code=400,
                    detail={
                        "error": f"expires_after[seconds] must be a valid integer, got '{expires_after_seconds_str}': {e}",
                    },
                )

            # Use literal "created_at" (not variable) for TypedDict to satisfy Literal type

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Set expires_after[anchor] to 'created_at'.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at litellm/proxy/openai_files_endpoints/files_endpoints.py:424 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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