{"record":{"id":"c3c3290a01a38604","repo":"bytedance/deer-flow","slug":"failed-to-delete-file","errorCode":null,"errorMessage":"Failed to delete file","messagePattern":"Failed to delete file","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"frontend/src/core/uploads/api.ts","lineNumber":128,"sourceCode":"}\n\n/**\n * Delete an uploaded file\n */\nexport async function deleteUploadedFile(\n  threadId: string,\n  filename: string,\n): Promise<{ success: boolean; message: string }> {\n  const encodedFilename = encodeURIComponent(filename);\n  const response = await fetch(\n    `${getBackendBaseURL()}/api/threads/${threadId}/uploads/${encodedFilename}`,\n    {\n      method: \"DELETE\",\n    },\n  );\n\n  if (!response.ok) {\n    throw new Error(await readErrorDetail(response, \"Failed to delete file\"));\n  }\n\n  return response.json();\n}\n","sourceCodeStart":110,"sourceCodeEnd":133,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/frontend/src/core/uploads/api.ts#L110-L133","documentation":"deleteUploadedFile issues DELETE /api/threads/{threadId}/uploads/{encodedFilename} and throws on non-ok responses, preferring the gateway's detail (e.g. 'file not found') over this fallback.","triggerScenarios":"Deleting a file already removed server-side (404 after a race with another tab), deleting on a deleted thread (404), expired session (401), or storage backend failure (5xx).","commonSituations":"Two tabs both showing an attachments list; deleting in one makes the other's delete 404. Also cleanup retries after a partially failed upload.","solutions":["Check the DELETE status: treat 404 as success when the goal is removal (idempotent delete).","401: re-auth and retry.","5xx: verify storage health in gateway logs, then refresh the file list."],"exampleFix":"// before: 404 after a race surfaces as an error\nawait deleteUploadedFile(threadId, filename);\n\n// after: tolerate already-deleted\nconst res = await fetch(url, { method: 'DELETE' });\nif (!res.ok && res.status !== 404) { throw new Error(await readErrorDetail(res, 'Failed to delete file')); }","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await deleteUploadedFile(threadId, filename); } catch (e) { if (isNotFound(e)) { /* already gone: refresh list, treat as done */ } else { toast(e.message || 'Failed to delete file'); } }","preventionTips":["Treat 404 on delete as success (idempotent semantics) at the call site or in the api wrapper.","Optimistically remove the row and roll back only on non-404 failure.","Refresh the file list after any delete attempt to resync multi-tab state."],"tags":["upload","delete","api","idempotency","frontend"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}