{"record":{"id":"0fca96fd2fd26019","repo":"ATH-MaaS/Pixelle-Video","slug":"file-not-found-file-path","errorCode":null,"errorMessage":"File not found: {file_path}","messagePattern":"File not found: (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"api/routers/files.py","lineNumber":78,"sourceCode":"            \"data/templates/\",\n            \"resources/\",\n        ]\n        \n        # Check if path starts with allowed prefix, otherwise try output/\n        full_path = None\n        for prefix in allowed_prefixes:\n            if file_path.startswith(prefix):\n                full_path = file_path\n                break\n        \n        # If no prefix matched, assume it's in output/ (backward compatibility)\n        if full_path is None:\n            full_path = f\"output/{file_path}\"\n        \n        abs_path = Path.cwd() / full_path\n        \n        if not abs_path.exists():\n            raise HTTPException(status_code=404, detail=f\"File not found: {file_path}\")\n        \n        if not abs_path.is_file():\n            raise HTTPException(status_code=400, detail=f\"Path is not a file: {file_path}\")\n        \n        # Security: only allow access to specified directories\n        try:\n            rel_path = abs_path.relative_to(Path.cwd())\n            rel_path_str = str(rel_path)\n            \n            # Check if path starts with any allowed prefix\n            is_allowed = any(rel_path_str.startswith(prefix.rstrip('/')) for prefix in allowed_prefixes)\n            \n            if not is_allowed:\n                raise HTTPException(\n                    status_code=403, \n                    detail=f\"Access denied: only {', '.join(p.rstrip('/') for p in allowed_prefixes)} directories are accessible\"\n                )\n        except ValueError:","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/ATH-MaaS/Pixelle-Video/blob/848b054e4fae40dabc62ec58e960b573e83793ac/api/routers/files.py#L60-L96","documentation":"GET file handler resolves the requested path (against an optional full_path or the output/ directory) and returns 404 when the resolved absolute path does not exist on disk. The detail includes the client-supplied file_path so the caller knows which file was not found.","triggerScenarios":"GET to the files endpoint with a file_path whose resolved location (full_path or output/{file_path}) does not exist — wrong filename, file deleted or not yet generated, wrong working directory of the server, or a typo/URL-encoding mismatch in the path.","commonSituations":"Requesting an output artifact before the pipeline produced it; server restarted with a different CWD so relative output/ paths resolve elsewhere; filename case mismatch on case-sensitive filesystems; Docker container lacking the mounted output volume.","solutions":["Verify the file actually exists at output/{file_path} relative to the server's working directory.","Confirm the server process CWD matches the directory containing output/ (docker/workdir differences are common).","Check filename spelling and case; URL-encode special characters in the path.","If the file is generated by a prior step, run/complete that step before fetching.","In a container, ensure the output directory is volume-mounted and persisted."],"exampleFix":"// client-side check before requesting\nimport fs from 'fs';\n// before\nawait fetch(`/api/files/${filePath}`);\n// after\nif (!fs.existsSync(path.join('output', filePath))) {\n  throw new Error(`output/${filePath} not produced yet`);\n}\nawait fetch(`/api/files/${encodeURIComponent(filePath)}`);","handlingStrategy":"validation","validationCode":"import fs from 'fs';\nimport path from 'path';\nconst resolved = path.resolve('output', filePath);\nif (!fs.existsSync(resolved)) throw new Error(`File ${filePath} does not exist under output/`);\n// then call GET /api/files/{filePath}","typeGuard":null,"tryCatchPattern":"try {\n  const res = await fetch(`/api/files/${encodeURIComponent(filePath)}`);\n  if (res.status === 404) throw new Error(`File not found on server: ${filePath}`);\n  if (!res.ok) throw new Error(`File fetch failed: ${res.status}`);\n  return await res.blob();\n} catch (err) {\n  logger.error('File fetch failed', err);\n  throw err;\n}","preventionTips":["Generate/verify the artifact before requesting it.","Encode file paths in URLs to avoid separator/encoding issues.","Keep the server's working directory stable (fixed workdir in Docker/systemd).","Watch for case-sensitivity differences between dev and prod filesystems."],"tags":["http-404","filesystem","path-resolution"],"backgroundTag":"file-not-found","analyzedSha":"848b054e4fae40dabc62ec58e960b573e83793ac","analyzedAt":"2026-08-30T03:24:41.468Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}