{"record":{"id":"2afb7fe3692787ec","repo":"bytedance/deer-flow","slug":"failed-to-acquire-sandbox","errorCode":null,"errorMessage":"Failed to acquire sandbox","messagePattern":"Failed to acquire sandbox","errorType":"http","errorClass":"HTTPException","httpStatus":500,"severity":"error","filePath":"backend/app/gateway/routers/uploads.py","lineNumber":339,"sourceCode":"    sandbox_uploads = uploads_dir\n    uploaded_files = []\n    written_paths = []\n    sandbox_sync_targets = []\n    skipped_files = []\n    total_size = 0\n    # Track filenames within this request so duplicate form parts do not\n    # silently truncate each other. Existing uploads keep the historical\n    # overwrite behavior for a single replacement upload.\n    seen_filenames: set[str] = set()\n\n    sandbox_provider = get_sandbox_provider()\n    sync_to_sandbox = not _uses_thread_data_mounts(sandbox_provider)\n    sandbox = None\n    if sync_to_sandbox:\n        sandbox_id = await sandbox_provider.acquire_async(thread_id, user_id=effective_user_id)\n        sandbox = sandbox_provider.get(sandbox_id)\n        if sandbox is None:\n            raise HTTPException(status_code=500, detail=\"Failed to acquire sandbox\")\n    auto_convert_documents = _auto_convert_documents_enabled(config)\n\n    for file in files:\n        if not file.filename:\n            continue\n\n        try:\n            original_filename = normalize_filename(file.filename)\n            safe_filename = claim_unique_filename(original_filename, seen_filenames)\n        except ValueError:\n            logger.warning(f\"Skipping file with unsafe filename: {file.filename!r}\")\n            continue\n\n        try:\n            file_path, file_size, total_size = await _write_upload_file_with_limits(\n                file,\n                uploads_dir=uploads_dir,\n                display_filename=safe_filename,","sourceCodeStart":321,"sourceCodeEnd":357,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/backend/app/gateway/routers/uploads.py#L321-L357","documentation":"HTTP 500 raised when the sandbox provider reports success from acquire_async(thread_id) but get(sandbox_id) then returns None — an internal inconsistency between the provider's acquire and get APIs. It means the gateway cannot obtain the sandbox handle needed to sync uploaded files into the thread's sandbox.","triggerScenarios":"Only on deployments whose sandbox provider uses file syncing (i.e. _uses_thread_data_mounts is false): acquire_async returns an id, but the corresponding sandbox record is missing/expired by the time get() is called.","commonSituations":"Sandbox registry TTL expiring between acquire and get; a custom sandbox provider with a bug where acquire does not register the sandbox; sandbox backend (container/K8s) crash or eviction mid-request.","solutions":["Retry the upload once — transient races between acquire and get often clear.","Check sandbox provider logs/health (container runtime, provisioner on port 8002 if configured) for crashes or evictions.","If running a custom sandbox provider, ensure acquire_async registers the sandbox so a subsequent get(sandbox_id) succeeds.","As a workaround, switch the deployment to a sandbox provider that uses thread data mounts (sync_to_sandbox becomes false and this path is skipped)."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"catch 500 with detail 'Failed to acquire sandbox'; retry the upload once after a short delay; escalate to the operator if it repeats.","preventionTips":["Monitor sandbox provider health (container runtime / provisioner) alongside the gateway.","Prefer sandbox providers using thread data mounts, which skip the acquire/sync path entirely.","Keep sandbox registry TTLs comfortably longer than the longest upload request."],"tags":["sandbox","http-500","upload","internal-error"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}