garrytan/gstack · error · Error
File not found
Error message
File not found
What it means
Thrown by validateTempPath (the GET /file remote-serving validator) when realpathSync fails with ENOENT — the file simply does not exist. This fires before any safety check, giving a clear 'File not found' to the remote agent rather than a confusing sandbox error.
Source
Thrown at browse/src/path-security.ts:109
} else {
throw new Error(`Cannot resolve real path: ${filePath} (${err.code})`);
}
}
const isSafe = SAFE_DIRECTORIES.some(dir => isPathWithin(realPath, dir));
if (!isSafe) {
throw new Error(`Path must be within: ${SAFE_DIRECTORIES.join(', ')}`);
}
}
/** Validate a file path for remote serving (GET /file). TEMP_DIR only, not cwd. */
export function validateTempPath(filePath: string): void {
const resolved = path.resolve(filePath);
let realPath: string;
try {
realPath = fs.realpathSync(resolved);
} catch (err: any) {
if (err.code === 'ENOENT') {
throw new Error('File not found');
}
throw new Error(`Cannot resolve path: ${filePath}`);
}
const isSafe = TEMP_ONLY.some(dir => isPathWithin(realPath, dir));
if (!isSafe) {
throw new Error(`Path must be within: ${TEMP_ONLY.join(', ')} (remote file serving is restricted to temp directory)`);
}
}
/** Escape special regex metacharacters in a user-supplied string to prevent ReDoS. */
export function escapeRegExp(s: string): string {
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
View on GitHub (pinned to 94993f7401)
Solutions
- Verify the file exists in TEMP_DIR before requesting it: `ls -la <TEMP_DIR>/<name>`
- Regenerate the artifact (re-run the screenshot/pdf/download command) and fetch again
- Check the exact filename and TEMP_DIR location — print TMPDIR/os.tmpdir() to confirm
- Fetch immediately after generation to avoid temp cleanup windows
Defensive patterns
Strategy: validation
Validate before calling
import * as fs from 'fs';
function tempFileExists(p: string): boolean {
try { fs.accessSync(p, fs.constants.R_OK); return true; }
catch { return false; }
}
if (!tempFileExists(filePath)) {
return { status: 404, body: 'File not found — generate it first' };
} Type guard
function isExistingTempFile(p: string): boolean {
try { const s = fs.statSync(p); return s.isFile(); } catch { return false; }
} Try / catch
try {
return serveTempFile(filePath);
} catch (e: any) {
if (e.message === 'File not found') return { status: 404, body: 'File not found' };
throw e;
} Prevention
- Fetch the artifact immediately after generation to avoid temp cleanup windows
- Have the generator return the exact filename and pass it through verbatim
- Confirm os.tmpdir() matches between writer and reader processes
- Log the file path at write time so the reader knows what to request
When it happens
Trigger: A remote agent requests GET /file?path=<something> and the file does not exist in TEMP_DIR: it was never written, was already deleted by temp cleanup, or the filename is wrong.
Common situations: Screenshot/pdf not yet generated when the remote agent fetches it; OS temp cleanup (systemd-tmpfiles) wiped the file between write and read; wrong filename in the request; race between writer and reader.
Related errors
- Cannot resolve path: ${filePath}
- State not found: ${statePath}
- Path must be within: ${TEMP_ONLY.join(', ')} (remote file se
- Skill "${name}" not found in any tier.
- Skill "${name}" not found.
AI-assisted analysis of garrytan/gstack@94993f7401 (2026-08-12).
Data as JSON: /api/errors/c8e61e7871faf793.
Report an issue: GitHub.