{"record":{"id":"6eeaecb3de183680","repo":"danny-avila/LibreChat","slug":"openai-returned-false-for-deleted-status","errorCode":null,"errorMessage":"OpenAI returned `false` for deleted status","messagePattern":"OpenAI returned `false` for deleted status","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"api/server/services/Files/OpenAI/crud.js","lineNumber":53,"sourceCode":"    await sleep(sleepTime);\n  }\n\n  return isImage ? { ...uploadedFile, height, width } : uploadedFile;\n}\n\n/**\n * Deletes a file previously uploaded to OpenAI.\n *\n * @param {ServerRequest} req - The request object from Express.\n * @param {MongoFile} file - The database representation of the uploaded file.\n * @param {OpenAI} openai - The initialized OpenAI client.\n * @returns {Promise<void>}\n */\nasync function deleteOpenAIFile(req, file, openai) {\n  try {\n    const res = await openai.files.del(file.file_id);\n    if (!res.deleted) {\n      throw new Error('OpenAI returned `false` for deleted status');\n    }\n    logger.debug(\n      `[deleteOpenAIFile] User ${req.user.id} successfully deleted file \"${file.file_id}\" from OpenAI`,\n    );\n  } catch (error) {\n    logger.error('[deleteOpenAIFile] Error deleting file from OpenAI: ' + error.message);\n    throw error;\n  }\n}\n\n/**\n * Retrieves a readable stream for a file from local storage.\n *\n * @param {string} file_id - The file_id.\n * @param {OpenAI} openai - The initialized OpenAI client.\n * @returns {Promise<ReadableStream>} A readable stream of the file.\n */\nasync function getOpenAIFileStream(file_id, openai) {","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/danny-avila/LibreChat/blob/5ff282f9006c436e561de1afd39a481bea1ef0d8/api/server/services/Files/OpenAI/crud.js#L35-L71","documentation":"Thrown by deleteOpenAIFile when the OpenAI Files API responds to a deletion request with { deleted: false } instead of { deleted: true }. The OpenAI SDK's files.del() method returns an object with a deleted boolean; a false value means the API acknowledged the request but did not confirm deletion. This is distinct from an HTTP error (which would throw from the SDK itself) — the API returned a 200-level response with a negative result.","triggerScenarios":"Calling deleteOpenAIFile(req, file, openai) where openai.files.del(file.file_id) resolves successfully but the response body contains deleted: false. This can occur if the file_id is invalid, the file was already deleted, or the OpenAI API has a transient issue returning the correct status.","commonSituations":"A file was already deleted from OpenAI (e.g., via a previous request or automatic cleanup) and the API returns deleted: false on a redundant deletion. Or the file_id stored in the database is stale, pointing to a file that no longer exists on OpenAI's servers. Or an OpenAI API version change altered the response contract.","solutions":["Check if the file was already deleted — this error is often benign for already-removed files.","Verify file.file_id is a valid OpenAI file identifier and matches a currently existing file via openai.files.retrieve(file_id).","Update the OpenAI SDK to the latest version in case the response contract changed.","Wrap the call and treat deleted: false as idempotent success if the file no longer exists on retrieval."],"exampleFix":"// before\nawait deleteOpenAIFile(req, file, openai);\n\n// after — treat already-deleted as success\ntry {\n  await deleteOpenAIFile(req, file, openai);\n} catch (error) {\n  if (error.message.includes('returned `false` for deleted status')) {\n    try {\n      await openai.files.retrieve(file.file_id);\n    } catch (retrieveError) {\n      if (retrieveError.status === 404) {\n        logger.info(`File ${file.file_id} already deleted from OpenAI`);\n        return;\n      }\n    }\n  }\n  throw error;\n}","handlingStrategy":"try-catch","validationCode":"try {\n  await openai.files.retrieve(file.file_id);\n} catch (error) {\n  if (error.status === 404) {\n    // file already deleted — safe to skip\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await deleteOpenAIFile(req, file, openai);\n} catch (error) {\n  if (error.message.includes('returned `false` for deleted status')) {\n    try {\n      await openai.files.retrieve(file.file_id);\n    } catch (retrieveError) {\n      if (retrieveError.status === 404) {\n        logger.info(`File ${file.file_id} already deleted from OpenAI`);\n        return; // treat as success\n      }\n    }\n  }\n  throw error;\n}","preventionTips":["Treat deleted: false as idempotent when the file is confirmed gone via retrieve returning 404.","Keep file.file_id in sync with OpenAI's file registry — run periodic reconciliation.","Update the OpenAI SDK to the latest version to ensure response contract compatibility.","Log deletion attempts and outcomes for audit trails."],"tags":["openai","file-deletion","api","external-service"],"backgroundTag":null,"analyzedSha":"5ff282f9006c436e561de1afd39a481bea1ef0d8","analyzedAt":"2026-08-12T21:38:08.145Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}