ATH-MaaS/Pixelle-Video · error · HTTPException

Path is not a file: {file_path}

Error message

Path is not a file: {file_path}

What it means

After confirming existence, the handler checks abs_path.is_file() and returns 400 when the path exists but is a directory (or other non-regular file). This endpoint only serves file contents, so directories are rejected.

Source

Thrown at api/routers/files.py:81

        
        # Check if path starts with allowed prefix, otherwise try output/
        full_path = None
        for prefix in allowed_prefixes:
            if file_path.startswith(prefix):
                full_path = file_path
                break
        
        # If no prefix matched, assume it's in output/ (backward compatibility)
        if full_path is None:
            full_path = f"output/{file_path}"
        
        abs_path = Path.cwd() / full_path
        
        if not abs_path.exists():
            raise HTTPException(status_code=404, detail=f"File not found: {file_path}")
        
        if not abs_path.is_file():
            raise HTTPException(status_code=400, detail=f"Path is not a file: {file_path}")
        
        # Security: only allow access to specified directories
        try:
            rel_path = abs_path.relative_to(Path.cwd())
            rel_path_str = str(rel_path)
            
            # Check if path starts with any allowed prefix
            is_allowed = any(rel_path_str.startswith(prefix.rstrip('/')) for prefix in allowed_prefixes)
            
            if not is_allowed:
                raise HTTPException(
                    status_code=403, 
                    detail=f"Access denied: only {', '.join(p.rstrip('/') for p in allowed_prefixes)} directories are accessible"
                )
        except ValueError:
            raise HTTPException(status_code=403, detail="Access denied")
        
        # Determine media type

View on GitHub (pinned to 848b054e4f)

Solutions

  1. Point file_path at a regular file, not a directory (append the concrete filename).
  2. If you need a folder of artifacts, request each file individually or add a zip/archive endpoint.
  3. Check the client path-building logic for missing filename or stray trailing slash.
  4. Verify with the listing endpoint (if available) which concrete filenames exist.

Example fix

// before
const res = await fetch(`/api/files/${folder}/`); // resolves to a directory
// after
const res = await fetch(`/api/files/${folder}/frame_0001.mp4`);
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'fs';
const stat = fs.statSync(path.resolve('output', filePath));
if (!stat.isFile()) throw new Error(`${filePath} is not a regular file`);

Prevention

When it happens

Trigger: GET to the files endpoint with a file_path that resolves to a directory inside output/ or the allowed roots — e.g. requesting 'output' itself, a subfolder, or an empty path segment that resolves to a directory.

Common situations: Client builds the URL from a path that includes a trailing directory component; requesting a bundle/folder expecting the server to zip it; passing a prefix path where a filename was expected.

Related errors


AI-assisted analysis of ATH-MaaS/Pixelle-Video@848b054e4f (2026-08-30). Data as JSON: /api/errors/6609cea3ac2e51a0. Report an issue: GitHub.