BerriAI/litellm · warning · HTTPException

Cannot delete file {file_id}. The file is referenced by {cou

Error message

Cannot delete file {file_id}. The file is referenced by {count} batch(es) in non-terminal state: {batch_statuses}. To delete this file before complete cost tracking, please delete or cancel the referencing batch(es) first. Alternatively, wait for all batches to complete and for cost to be computed (batch_processed=true).

What it means

afile_delete guards batch cost tracking: a managed file cannot be deleted while any batch referencing it is in a non-terminal state, because cost computation still needs the file. The 400 detail lists the referencing batch ids and statuses (capped at MAX_BATCHES_IN_ERROR most recent), a 'blocked' Prometheus metric is recorded, and remediation steps are embedded.

Source

Thrown at enterprise/litellm_enterprise/proxy/hooks/managed_files.py:1528

            )

            # Add specific batch details if not too many
            if len(referencing_batches) <= MAX_BATCHES_IN_ERROR:
                error_message += f": {', '.join(batch_statuses)}. "
            else:
                error_message += f" (showing {MAX_BATCHES_IN_ERROR} most recent): {', '.join(batch_statuses)}. "

            error_message += (
                "To delete this file before complete cost tracking, please delete or cancel the referencing batch(es) first. "
                "Alternatively, wait for all batches to complete and for cost to be computed (batch_processed=true)."
            )

            # Record blocked deletion metric
            prom_logger = self._get_prometheus_logger()
            if prom_logger:
                prom_logger.record_managed_file_deleted(result="blocked")

            raise HTTPException(
                status_code=400,
                detail=error_message,
            )

    async def afile_delete(
        self,
        file_id: str,
        litellm_parent_otel_span: Optional[Span],
        llm_router: Router,
        **data: Dict,
    ) -> OpenAIFileObject:

        # Check if file deletion should be blocked due to batch references
        await self._check_file_deletion_allowed(file_id)

        # file_id = convert_b64_uid_to_unified_uid(file_id)
        model_file_id_mapping = await self.get_model_file_id_mapping([file_id], litellm_parent_otel_span)

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Cancel or delete the referencing batches first (POST /v1/batches/{batch_id}/cancel or the batch delete endpoint), then retry the file delete
  2. Wait for all referencing batches to reach a terminal state and for cost to be computed (batch_processed=true)
  3. Make cleanup scripts parse the batch ids from this error and skip or defer those files

Example fix

# before
curl -X DELETE http://0.0.0.0:4000/v1/files/{file_id} -H 'Authorization: Bearer sk-1234'  # 400 while batch in_progress

# after
curl -X POST http://0.0.0.0:4000/v1/batches/{batch_id}/cancel -H 'Authorization: Bearer sk-1234'
curl -X DELETE http://0.0.0.0:4000/v1/files/{file_id} -H 'Authorization: Bearer sk-1234'
Defensive patterns

Strategy: validation

Validate before calling

batches = await list_batches_for_file(file_id)  # or list all and filter
non_terminal = {b.id for b in batches if b.status not in ("completed", "failed", "expired", "cancelled")}
if non_terminal:
    for bid in non_terminal:
        await cancel_batch(bid)
    await wait_until_batches_terminal(non_terminal)
await delete_file(file_id)

Try / catch

try:
    await proxy.files.delete(file_id)
except HTTPStatusError as e:
    if e.response.status_code == 400 and "non-terminal state" in e.response.text:
        # parse batch ids from detail, cancel/wait, then retry once
        ...

Prevention

When it happens

Trigger: DELETE /v1/files/{file_id} while at least one batch created from that file is in a non-terminal state (in_progress, validating, finalizing, ...) and batch_processed is not true.

Common situations: Cleanup crons that delete files right after submitting batches; very long-running batches; the batch cost-tracking job lagging behind batch completion.

Related errors


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