can1357/oh-my-pi · error · ToolError
Directory paths are not supported by read(): ${filePath}
Error message
Directory paths are not supported by read(): ${filePath} What it means
`resolveRegularFile` stats the resolved path with `Bun.file(...).stat()` before reading; if the target is a directory, `read()` throws this ToolError because `file.text()` cannot return directory content. Only regular files are readable through the sandbox read helper.
Source
Thrown at packages/coding-agent/src/eval/js/shared/helpers.ts:154
if (normalized.startsWith("..") || normalized.includes("/../") || normalized.includes("/..")) {
throw new ToolError(`Path traversal (..) is not allowed in ${scheme}:// URLs: ${rawPath}`);
}
const resolved = path.resolve(rootPath, normalized);
if (resolved !== rootPath && !resolved.startsWith(`${rootPath}${path.sep}`)) {
throw new ToolError(`${scheme}:// path escapes its root: ${rawPath}`);
}
return resolved;
}
async function resolveRegularFile(
ctx: HelperContext,
rawPath: string,
): Promise<{ filePath: string; file: Bun.BunFile; size: number }> {
const filePath = resolveHelperPath(ctx, rawPath, "read");
const file = Bun.file(filePath);
const stat = await file.stat();
if (stat.isDirectory()) {
throw new ToolError(`Directory paths are not supported by read(): ${filePath}`);
}
return { filePath, file, size: stat.size };
}
function getDataSize(data: string | Blob | ArrayBuffer | ArrayBufferView): number {
if (typeof data === "string") return utf8Encoder.encode(data).byteLength;
if (data instanceof Blob) return data.size;
if (data instanceof ArrayBuffer) return data.byteLength;
return data.byteLength;
}
function isWriteData(value: unknown): value is string | Blob | ArrayBuffer | ArrayBufferView {
return (
typeof value === "string" || value instanceof Blob || value instanceof ArrayBuffer || ArrayBuffer.isView(value)
);
}
View on GitHub (pinned to 9690622007)
Solutions
- Read a specific file inside the directory, e.g. `read("src/index.ts")`.
- If you need directory listing, use the session's file-listing tool (e.g. glob/ls) instead of the read helper.
- Verify the target path exists as a file before reading (stat or a filesystem check).
Example fix
// before
const txt = await read("src");
// after
const txt = await read("src/index.ts"); Defensive patterns
Strategy: validation
Validate before calling
const stat = await Bun.file(path).stat();
if (stat?.isDirectory()) throw new Error(`${path} is a directory`); Try / catch
try {
return await read(p);
} catch (err) {
if (String(err?.message).startsWith("Directory paths are not supported")) {
return await read(path.join(p, "index.ts")); // or surface a listing tool instead
}
throw err;
} Prevention
- Stat or glob the target before reading when the path comes from dynamic input.
- Use the listing tool for directories instead of read().
- Strip trailing slashes from directory-looking inputs before constructing the read call.
When it happens
Trigger: Calling `read()` on a directory path — e.g. `read("src")`, `read("local://reports/")` — where the resolved path is an existing directory.
Common situations: Pointing read at a folder expecting it to list contents or concatenate files; stale assumptions after a path became a directory; trailing-slash confusion.
Related errors
- Protocol paths are not supported by ${op}(): ${rawPath}
- write() expects string, Blob, ArrayBuffer, or TypedArray dat
- Invalid URL encoding in ${scheme}:// path: ${rawPath}
- Absolute paths are not allowed in ${scheme}:// URLs: ${rawPa
- Path traversal (..) is not allowed in ${scheme}:// URLs: ${r
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/238466dead2e0095.
Report an issue: GitHub.