{"record":{"id":"a0fb074b4630e74f","repo":"Mintplex-Labs/anything-llm","slug":"failed-to-download-file-a0fb07","errorCode":null,"errorMessage":"Failed to download file","messagePattern":"Failed to download file","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"server/endpoints/agentFileServer.js","lineNumber":85,"sourceCode":"        // Get mime type and set headers for download\n        const mimeType = createFilesLib.getMimeType(`.${parsed.extension}`);\n        const safeFilename = createFilesLib.sanitizeFilenameForHeader(\n          fileSource.displayFilename || filename\n        );\n        response.setHeader(\"Content-Type\", mimeType);\n        response.setHeader(\n          \"Content-Disposition\",\n          `attachment; filename=\"${safeFilename}\"`\n        );\n        response.setHeader(\"Content-Length\", fileData.buffer.length);\n        response.send(fileData.buffer);\n        Telemetry.sendTelemetry(\"agent_generated_file_downloaded\", {\n          type: mimeType,\n        }).catch(() => {});\n        return;\n      } catch (error) {\n        console.error(\"[agentFileServer] Download error:\", error.message);\n        return response.status(500).json({ error: \"Failed to download file\" });\n      }\n    }\n  );\n\n  /**\n   * Serve a generated image inline (so it can be used as an <img> src).\n   * Validates that the requesting user has access to a chat that references\n   * the image before serving it from storage/generated-images.\n   */\n  app.get(\n    \"/image-generation/generated-images/:filename\",\n    [validatedRequest, flexUserRoleValid([ROLES.all])],\n    async (request, response) => {\n      try {\n        const fs = require(\"fs\");\n        const path = require(\"path\");\n        const {\n          generatedImagesPath,","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/3aec848f2885144aa8f1e53b9731a04310d5d558/server/endpoints/agentFileServer.js#L67-L103","documentation":"Catch-all HTTP 500 from the generated-files download handler. Anything that throws after the early guards — setting headers (e.g. invalid characters in the sanitized display filename), an unexpected shape from getGeneratedFile (missing buffer), response.send failures, or client-abort edge cases — is logged as '[agentFileServer] Download error: <message>' server-side and returned to the client as this generic message. The console.error line is the only place the real cause appears.","triggerScenarios":"fileData.buffer undefined because storage returned a record without content; Content-Disposition header containing newline/quote characters from a malformed displayFilename; socket closed by the client between the guards and response.send; ENOSPC or permission errors while streaming from the storage driver.","commonSituations":"Diagnosing production download failures where the HTTP message alone is useless; downloads that fail only for specific files (bad display names); transient failures under load that disappear on retry.","solutions":["Correlate with the server console at the request timestamp — the '[agentFileServer] Download error:' line holds the actual error message","Retry once; transient stream aborts and races often clear","Manually verify the file exists in the storage directory and getGeneratedFile returns a buffer for that name","If persistent, temporarily log the full error object (not just error.message) in the catch to get a stack, then fix the specific fault"],"exampleFix":"// before: only the message is logged, stacks are lost\nconsole.error('[agentFileServer] Download error:', error.message);\n\n// after: capture the stack while investigating\nconsole.error('[agentFileServer] Download error:', error);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const res = await fetch(url, {credentials: 'include'});\n  if (res.status === 500) {\n    // generic by design — the '[agentFileServer] Download error:' server log\n    // at this timestamp holds the actual cause; retry once for transient aborts\n    return await fetch(url, {credentials: 'include'});\n  }\n} catch (e) {\n  // client/network-level failure\n}","preventionTips":["Always correlate these 500s with server logs before changing client code","Retry once — mid-stream aborts are frequently transient","Sanitize display filenames (strip quotes/newlines) before they reach Content-Disposition"],"tags":["http-500","file-download","generic-catch","diagnostics"],"backgroundTag":"internal-server-error","analyzedSha":"3aec848f2885144aa8f1e53b9731a04310d5d558","analyzedAt":"2026-08-18T10:02:21.017Z","contentChangedAt":"2026-08-18T10:02:21.017Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}