{"record":{"id":"49f579034f05cd66","repo":"Mintplex-Labs/anything-llm","slug":"invalid-filename","errorCode":null,"errorMessage":"Invalid filename","messagePattern":"Invalid filename","errorType":"http","errorClass":null,"httpStatus":400,"severity":"warning","filePath":"server/endpoints/agentFileServer.js","lineNumber":110,"sourceCode":"   * 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,\n          GENERATED_IMAGE_FILENAME_PATTERN,\n        } = require(\"../utils/files\");\n        const user = await userFromSession(request, response);\n        const { filename } = request.params;\n\n        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\" });","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/3aec848f2885144aa8f1e53b9731a04310d5d558/server/endpoints/agentFileServer.js#L92-L128","documentation":"Returned (HTTP 400) by GET /image-generation/generated-images/:filename when the name fails GENERATED_IMAGE_FILENAME_PATTERN = /^img-[a-f0-9-]{36}\\.png$/i (utils/files/index.js:881). Generated images are stored strictly as img-<uuid>.png; this single check covers both the missing-filename case and format violations. Any other name — display names, other extensions, uuids of the wrong length — is rejected before the database lookup.","triggerScenarios":"GET /image-generation/generated-images/sunset.png (display/prompt-derived name instead of img-<uuid>.png); names ending in .jpg or .webp; a uuid segment not exactly 36 hex/dash chars; querystrings or encoded slashes folded into the param.","commonSituations":"Using the image's pretty filename from the chat message instead of the storage src the backend returned; older deployments before the img- convention; clients re-encoding the URL once too many times.","solutions":["Use the exact img-<uuid>.png storage filename from the <img> tag/chat payload","When generating links programmatically, validate against /^img-[a-f0-9-]{36}\\.png$/i first","If you truly have a jpg/webp artifact, it belongs to a different endpoint — not this one"],"exampleFix":"// before: display name fails the pattern\nconst src = `/image-generation/generated-images/${encodeURIComponent('a cat at sunset.png')}`; // 400\n\n// after: use the storage filename the API returned\nconst src = `/image-generation/generated-images/${encodeURIComponent(result.storageFilename)}`; // img-<uuid>.png","handlingStrategy":"type-guard","validationCode":"const GENERATED_IMAGE_FILENAME_PATTERN = /^img-[a-f0-9-]{36}\\.png$/i;\nif (!GENERATED_IMAGE_FILENAME_PATTERN.test(name))\n  throw new Error(`not a generated-image storage name: ${name}`);","typeGuard":"function isGeneratedImageFilename(name) {\n  return typeof name === 'string' && /^img-[a-f0-9-]{36}\\.png$/i.test(name);\n}","tryCatchPattern":"try { const buf = await fetchImage(name); }\ncatch (e) {\n  if (e.status === 400 && /invalid filename/i.test(e.body?.error ?? ''))\n    throw new Error('expected an img-<uuid>.png storage name from the generation result');\n}","preventionTips":["Bind <img> tags to the storageFilename returned by the image-generation result, never the prompt-derived display name","Keep the client regex in lockstep with GENERATED_IMAGE_FILENAME_PATTERN in server/utils/files/index.js","Reject non-png artifacts before routing them to this endpoint"],"tags":["http-400","filename-validation","image-generation","uuid-format"],"backgroundTag":"invalid-filename-format","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"}