{"record":{"id":"381904fd703d2a4b","repo":"can1357/oh-my-pi","slug":"openai-files-api-delete-failed-with-http-respons","errorCode":null,"errorMessage":"OpenAI Files API delete failed with HTTP ${response.status}","messagePattern":"OpenAI Files API delete failed with HTTP (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/coding-agent/src/blob-broker/provider-files-openai.ts","lineNumber":141,"sourceCode":"\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\tasync delete(handle: ProviderFileHandle): Promise<void> {\n\t\t\tif (handle.provider !== \"openai\" || typeof handle.id !== \"string\" || handle.id.trim().length === 0) {\n\t\t\t\tthrow new Error(\"Cannot delete an invalid OpenAI file handle\");\n\t\t\t}\n\n\t\t\tlet response: Response;\n\t\t\ttry {\n\t\t\t\tresponse = await request(`${OPENAI_FILES_URL}/${encodeURIComponent(handle.id)}`, {\n\t\t\t\t\tmethod: \"DELETE\",\n\t\t\t\t\theaders: { Authorization: authorization },\n\t\t\t\t});\n\t\t\t} catch {\n\t\t\t\tthrow new Error(\"OpenAI Files API delete request failed\");\n\t\t\t}\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(`OpenAI Files API delete failed with HTTP ${response.status}`);\n\t\t\t}\n\t\t},\n\t};\n}\n","sourceCodeStart":123,"sourceCodeEnd":146,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/blob-broker/provider-files-openai.ts#L123-L146","documentation":"Thrown when the DELETE request reached OpenAI but returned a non-2xx status. The most common case is 404 — the file was already deleted — followed by 401/403 (auth) and 5xx (outage). The status is interpolated into the message.","triggerScenarios":"client.delete() with response.ok === false: 404 (file already gone / never existed), 401 (bad key), 403 (key can't access that org's files), 429/5xx (rate limit/outage).","commonSituations":"Double-cleanup of the same handle (404); key rotated between upload and delete (401); deleting a file uploaded under a different org/project key (404/403).","solutions":["Treat HTTP 404 as success — the goal (file gone) is already achieved; skip or log-and-continue","For 401/403, verify the same credential used for the upload is used for the delete","For 429/5xx, retry with exponential backoff","If persists, check the OpenAI dashboard whether the file exists under the expected project/org"],"exampleFix":"// before: 404 on already-deleted file crashes cleanup\nawait client.delete(handle);\n// after\ntry {\n  await client.delete(handle);\n} catch (err) {\n  const status = Number(/HTTP (\\d{3})/.exec(String(err.message))?.[1] ?? 0);\n  if (status !== 404) throw err; // idempotent delete: 404 means goal achieved\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isAlreadyDeleted(err: unknown): boolean {\n  const m = /HTTP (\\d{3})/.exec(err instanceof Error ? err.message : \"\");\n  return m?.[1] === \"404\";\n}","tryCatchPattern":"try {\n  await client.delete(handle);\n} catch (err) {\n  if (isAlreadyDeleted(err)) return; // file already gone: success\n  if (isRetryableHttpStatus(err)) return queueRetry(() => client.delete(handle));\n  throw err;\n}","preventionTips":["Guard against double-cleanup with a deleted-handle set","Reuse the exact credential/org that performed the upload for the delete","Retry 429/5xx deletes with backoff","Log the interpolated HTTP status for diagnosis"],"tags":["http","openai","delete","api-error"],"backgroundTag":"http-api-error","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}