Significant-Gravitas/AutoGPT · warning · HTTPException

Expiration hours must be between 1 and 48

Error message

Expiration hours must be between 1 and 48

What it means

HTTP 400 from the cloud-storage upload endpoint when expiration_hours is outside the allowed 1-48 window. The signed URL issued by the provider (gcs/s3/azure) is only valid for that bounded range, so the route rejects anything under 1 hour or over 48 hours before reading the file body.

Source

Thrown at autogpt_platform/backend/backend/api/features/v1.py:598

    ctx: Annotated[RequestContext, Security(get_request_context)],
    file: UploadFile = File(...),
    expiration_hours: int = 24,
) -> UploadFileResponse:
    """
    Upload a file to cloud storage and return a storage key that can be used
    with FileStoreBlock and AgentFileInputBlock.

    Args:
        file: The file to upload
        user_id: The user ID
        provider: Cloud storage provider ("gcs", "s3", "azure")
        expiration_hours: Hours until file expires (1-48)

    Returns:
        Dict containing the cloud storage path and signed URL
    """
    if expiration_hours < 1 or expiration_hours > 48:
        raise HTTPException(
            status_code=400, detail="Expiration hours must be between 1 and 48"
        )

    # Check file size limit before reading content to avoid memory issues
    max_size_mb = settings.config.upload_file_size_limit_mb
    max_size_bytes = max_size_mb * 1024 * 1024

    # Try to get file size from headers first
    if hasattr(file, "size") and file.size is not None and file.size > max_size_bytes:
        raise _create_file_size_error(file.size, max_size_mb)

    # Read file content
    content = await file.read()
    content_size = len(content)

    # Double-check file size after reading (in case header was missing/incorrect)
    if content_size > max_size_bytes:
        raise _create_file_size_error(content_size, max_size_mb)

View on GitHub (pinned to 9c8bb5550f)

Solutions

  1. Send an integer expiration_hours between 1 and 48 inclusive
  2. Clamp the user-supplied value in the client before calling the API: Math.min(48, Math.max(1, hours))
  3. If longer-lived files are needed, use the regular file-storage endpoints instead of the signed-URL cloud upload

Example fix

# before
expiration_hours = 0.5  # intended '30 minutes' -> 400

# after
expiration_hours = 1  # minimum allowed
Defensive patterns

Strategy: validation

Validate before calling

const hours = Math.round(Math.min(48, Math.max(1, userHours)));

Type guard

function isValidExpirationHours(h: unknown): h is number {
  return typeof h === "number" && Number.isInteger(h) && h >= 1 && h <= 48;
}

Prevention

When it happens

Trigger: POST of a file to the upload-to-cloud endpoint with expiration_hours=0, negative, fractional-but-clamped-out values like 0.5, or values > 48 (e.g. 72 for a 3-day link).

Common situations: Copy-pasting an expiry in minutes instead of hours (e.g. 30 meaning 30 minutes but sent as 30 hours, or 0.5 meaning half an hour); defaults from another API that allows 7-day links; UI sliders or env config with unbounded ranges.

Related errors


AI-assisted analysis of Significant-Gravitas/AutoGPT@9c8bb5550f (2026-08-14). Data as JSON: /api/errors/14a6e766f271dde0. Report an issue: GitHub.