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
- Cancel or delete the referencing batches first (POST /v1/batches/{batch_id}/cancel or the batch delete endpoint), then retry the file delete
- Wait for all referencing batches to reach a terminal state and for cost to be computed (batch_processed=true)
- 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
- Make file cleanup jobs batch-aware: check batch statuses before deleting
- Never delete inputs to in-flight batches in the same pipeline run
- Wait for batch_processed=true before end-of-job cleanup
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
- LiteLLM Managed File object with id={file_id} not found
- LLM Router not initialized. Ensure models added to proxy.
- LiteLLM Managed File object with id={file_id} has no file_ob
- Failed to retrieve file {file_id} from provider: {str(e)}
- LiteLLM Managed File object with id={file_id} not found. Che
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/0dd1cc6167e9c124.
Report an issue: GitHub.