invoke-ai/InvokeAI · error

Invalid image name, potential directory traversal detected

Error message

Invalid image name, potential directory traversal detected

What it means

ImageFileService.get_path validates that the image filename contains no path separators by comparing Path(filename).name to the original string. If they differ, the name embeds a directory component or traversal, so it raises this ValueError to prevent writing or reading outside the outputs folder.

Solutions

  1. Strip any directory components from the name before calling, or pass the directory via the image_subfolder parameter instead
  2. Sanitize the name with Path(name).name and verify it matches the input
  3. Reject the input at your API boundary with an allowlist regex (e.g. ^[A-Za-z0-9._-]+$)

Example fix

// before
service.save(Path('uploads/img.png').read_bytes(), 'subdir/img.png')
// after
service.save(Path('uploads/img.png').read_bytes(), 'img.png', image_subfolder='subdir')
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import PurePosixPath
import re
NAME_RE = re.compile(r'^[A-Za-z0-9][A-Za-z0-9._-]*$')
def is_safe_image_name(name: str) -> bool:
    return bool(NAME_RE.match(name)) and PurePosixPath(name).name == name
if not is_safe_image_name(image_name): raise ValueError('bad image name')

Type guard

def is_safe_image_name(name: object) -> bool:
    return isinstance(name, str) and '/' not in name and '\\' not in name and name not in ('', '.', '..')

Try / catch

try:
    path = service.get_path(image_name, thumbnail=False)
except ValueError as e:
    logger.warning('Rejected image name %r: %s', image_name, e)
    raise HTTPException(400, 'Invalid image name') from e

Prevention

When it happens

Trigger: Calling get/save/stage_delete with an image_name containing '/' or backslashes (e.g. '../foo.png' or 'sub/dir.png'), or a thumbnail name derived from such a name.

Common situations: Passing user-supplied or API-derived image names that include relative paths; storing images with names built by joining folder+file instead of using the image_subfolder parameter; older code predating the subfolder feature.

Related errors


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/a2b12718339f8fbe. Report an issue: GitHub.

Appendix: source

Thrown at invokeai/app/services/image_files/image_files_disk.py:259

        if not isinstance(token, _StagedDelete):
            raise ImageFileDeleteException("Invalid staged-delete token")
        try:
            for source, destination in reversed(token.files):
                if destination.exists():
                    source.parent.mkdir(parents=True, exist_ok=True)
                    destination.replace(source)
            shutil.rmtree(token.directory, ignore_errors=True)
        except Exception as e:
            raise ImageFileDeleteException from e

    def get_path(self, image_name: str, thumbnail: bool = False, image_subfolder: str = "") -> Path:
        base_folder = self.__thumbnails_folder if thumbnail else self.__output_folder
        filename = get_thumbnail_name(image_name) if thumbnail else image_name

        # Validate the filename itself (no path separators allowed in the filename)
        basename = Path(filename).name
        if basename != filename:
            raise ValueError("Invalid image name, potential directory traversal detected")

        # Build the full path with optional subfolder
        if image_subfolder:
            self._validate_subfolder(image_subfolder)
            image_path = base_folder / image_subfolder / basename
        else:
            image_path = base_folder / basename

        # Ensure the image path is within the base folder to prevent directory traversal
        resolved_base = base_folder.resolve()
        resolved_image_path = image_path.resolve()

        if not resolved_image_path.is_relative_to(resolved_base):
            raise ValueError("Image path outside outputs folder, potential directory traversal detected")

        return resolved_image_path

    @staticmethod

View on GitHub (pinned to 0b6a024f2f)