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

  1. Use the exact img-<uuid>.png storage filename from the <img> tag/chat payload
  2. When generating links programmatically, validate against /^img-[a-f0-9-]{36}\.png$/i first
  3. 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

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


AI-assisted analysis of Mintplex-Labs/anything-llm@3aec848f28 (2026-08-18). Data as JSON: /api/errors/49f579034f05cd66. Report an issue: GitHub.