{"record":{"id":"cfb043caaf4d447e","repo":"Mintplex-Labs/anything-llm","slug":"image-not-found-in-storage","errorCode":null,"errorMessage":"Image not found in storage","messagePattern":"Image not found in storage","errorType":"http","errorClass":null,"httpStatus":404,"severity":"warning","filePath":"server/endpoints/agentFileServer.js","lineNumber":127,"sourceCode":"        if (!filename || !GENERATED_IMAGE_FILENAME_PATTERN.test(filename))\n          return response.status(400).json({ error: \"Invalid filename\" });\n\n        const fileSource = await findFileSource(filename, {\n          user,\n          isMultiUser: multiUserMode(response),\n        });\n        if (!fileSource)\n          return response\n            .status(404)\n            .json({ error: \"Image not found or access denied\" });\n\n        const imagePath = path.resolve(generatedImagesPath, filename);\n        let imageBuffer;\n        try {\n          imageBuffer = await fs.promises.readFile(imagePath);\n        } catch {\n          return response\n            .status(404)\n            .json({ error: \"Image not found in storage\" });\n        }\n\n        response.setHeader(\"Content-Type\", \"image/png\");\n        return response.send(imageBuffer);\n      } catch (error) {\n        console.error(\"[agentFileServer] Image serve error:\", error.message);\n        return response.status(500).json({ error: \"Failed to serve image\" });\n      }\n    }\n  );\n}\n\n/**\n * Locates the source record (a workspace chat or a scheduled job run) that\n * references the given storage filename, and confirms the requester has access.\n *\n * Search order:","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/3aec848f2885144aa8f1e53b9731a04310d5d558/server/endpoints/agentFileServer.js#L109-L145","documentation":"Returned (HTTP 404) by GET /image-generation/generated-images/:filename when fs.promises.readFile(imagePath) throws — an accessible chat record references the image, but the file is missing from the generatedImagesPath directory (storage/generated-images by default). Authorization already passed; this is purely a disk-level miss, i.e. DB/storage desync.","triggerScenarios":"The generated-images directory was pruned while chat rows remain; generatedImagesPath resolves to a different location than where images were written (env or cwd differences — the path is resolved relative to the server); the volume is not mounted in the container serving the request; the file was manually deleted.","commonSituations":"Cleaning storage folders without cleaning history; moving the app to a new host or changing the storage root; docker deployments with missing volume mounts; restoring a DB backup without the matching storage backup.","solutions":["Confirm storage/generated-images actually contains the img-<uuid>.png file on the serving instance","Align the generated-images path configuration across every instance serving these URLs","Regenerate the image from the chat request","If pruning storage, expect old <img> links to land here — remove the referencing history too"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Operator preflight: authorizing record exists AND blob exists on the serving instance\nconst referenced = await chatHistoryMentions(storageFilename);\nconst onDisk = fs.existsSync(path.join(generatedImagesPath, storageFilename));\nif (referenced && !onDisk) console.warn('orphaned image reference:', storageFilename);","typeGuard":null,"tryCatchPattern":"try {\n  const res = await fetch(imgUrl, {credentials: 'include'});\n  if (res.status === 404) {\n    const body = await res.json();\n    if (body.error === 'Image not found in storage')\n      await regenerateImage(); // record exists, disk does not — nothing else recovers it\n  }\n} catch (e) { /* network failure */ }","preventionTips":["Keep storage/generated-images and the database on the same backup/restore schedule","Mount the same storage volume into every replica serving image URLs","Treat a missing-blob-with-existing-record as a data-integrity signal, not a client bug"],"tags":["http-404","storage","db-storage-desync","image-generation"],"backgroundTag":"file-missing-from-storage","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"}