Mintplex-Labs/anything-llm · warning
Invalid filename
Error message
Invalid filename
What it means
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.
Source
Thrown at server/endpoints/agentFileServer.js:110
* Validates that the requesting user has access to a chat that references
* the image before serving it from storage/generated-images.
*/
app.get(
"/image-generation/generated-images/:filename",
[validatedRequest, flexUserRoleValid([ROLES.all])],
async (request, response) => {
try {
const fs = require("fs");
const path = require("path");
const {
generatedImagesPath,
GENERATED_IMAGE_FILENAME_PATTERN,
} = require("../utils/files");
const user = await userFromSession(request, response);
const { filename } = request.params;
if (!filename || !GENERATED_IMAGE_FILENAME_PATTERN.test(filename))
return response.status(400).json({ error: "Invalid filename" });
const fileSource = await findFileSource(filename, {
user,
isMultiUser: multiUserMode(response),
});
if (!fileSource)
return response
.status(404)
.json({ error: "Image not found or access denied" });
const imagePath = path.resolve(generatedImagesPath, filename);
let imageBuffer;
try {
imageBuffer = await fs.promises.readFile(imagePath);
} catch {
return response
.status(404)
.json({ error: "Image not found in storage" });View on GitHub (pinned to 3aec848f28)
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
Example fix
// before: display name fails the pattern
const src = `/image-generation/generated-images/${encodeURIComponent('a cat at sunset.png')}`; // 400
// after: use the storage filename the API returned
const src = `/image-generation/generated-images/${encodeURIComponent(result.storageFilename)}`; // img-<uuid>.png Defensive patterns
Strategy: type-guard
Validate before calling
const GENERATED_IMAGE_FILENAME_PATTERN = /^img-[a-f0-9-]{36}\.png$/i;
if (!GENERATED_IMAGE_FILENAME_PATTERN.test(name))
throw new Error(`not a generated-image storage name: ${name}`); Type guard
function isGeneratedImageFilename(name) {
return typeof name === 'string' && /^img-[a-f0-9-]{36}\.png$/i.test(name);
} Try / catch
try { const buf = await fetchImage(name); }
catch (e) {
if (e.status === 400 && /invalid filename/i.test(e.body?.error ?? ''))
throw new Error('expected an img-<uuid>.png storage name from the generation result');
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Invalid filename format
- Image edit failed (${res.status}): ${body || res.statusText}
- Failed to fetch edited image: ${imgRes.status}
- Image edit returned no image data.
- Failed to fetch generated image: ${res.status}
AI-assisted analysis of Mintplex-Labs/anything-llm@3aec848f28 (2026-08-18).
Data as JSON: /api/errors/49f579034f05cd66.
Report an issue: GitHub.