can1357/oh-my-pi · error · ToolError
Absolute paths are not allowed in ${scheme}:// URLs: ${rawPa
Error message
Absolute paths are not allowed in ${scheme}:// URLs: ${rawPath} What it means
Internal-URL paths are treated as relative to the scheme's registered root; absolute paths inside a `scheme://` URL are rejected by `resolveUnderRoot` because they would bypass root confinement. This is a sandbox security boundary: only paths relative to the mounted root are legal.
Source
Thrown at packages/coding-agent/src/eval/js/shared/helpers.ts:133
if (!root) {
throw new ToolError(`Protocol paths are not supported by ${op}(): ${rawPath}`);
}
return resolveUnderRoot(scheme, root, match[2], rawPath);
}
/** Resolve an internal-URL relative path under its root, mirroring the host
* local-protocol handler: decode, reject absolute/traversal, confine to root. */
function resolveUnderRoot(scheme: string, root: string, rawRelative: string, rawPath: string): string {
let relative: string;
try {
relative = decodeURIComponent(rawRelative.replaceAll("\\", "/"));
} catch {
throw new ToolError(`Invalid URL encoding in ${scheme}:// path: ${rawPath}`);
}
const rootPath = path.resolve(root);
if (relative === "") return rootPath;
if (path.isAbsolute(relative)) {
throw new ToolError(`Absolute paths are not allowed in ${scheme}:// URLs: ${rawPath}`);
}
const normalized = path.normalize(relative);
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);View on GitHub (pinned to 9690622007)
Solutions
- Drop the leading slash: use `local://report.md` instead of `local:///report.md`.
- For genuine absolute filesystem locations, pass the absolute path directly (no scheme:// prefix) instead of an internal URL.
- Express the target relative to the scheme's mounted root directory.
Example fix
// before
await read("local:///etc/passwd");
// after
await read("/etc/passwd"); // or a root-relative: await read("local://reports/q3.md"); Defensive patterns
Strategy: validation
Validate before calling
const rel = url.replace(/^\w+:\/\//, "").replaceAll("\\", "/");
if (rel.startsWith("/") || /^[A-Za-z]:/.test(rel)) throw new Error("absolute path not allowed in scheme URL"); Try / catch
try {
return await read(url);
} catch (err) {
if (String(err?.message).startsWith("Absolute paths are not allowed")) {
const rel = url.replace(/^\w+:\/\/+/, "");
return await read(`${url.slice(0, url.indexOf("://"))}://${rel.replace(/^\/+/, "")}`);
}
throw err;
} Prevention
- Never prefix scheme:// paths with `/`.
- Keep absolute filesystem paths and internal URLs as separate, non-mixed forms.
- When joining a scheme with a variable path, strip leading slashes first.
When it happens
Trigger: Calling read()/write() with paths like `local:///etc/passwd` or `local://C:/data/file.txt` — the portion after `scheme://` begins with `/` (or is a Windows drive path) after decoding and backslash normalization.
Common situations: Prepending `/` out of habit when constructing scheme URLs; mixing ordinary absolute file paths with protocol syntax; generated code that joins scheme prefix with an absolute path variable.
Related errors
- Path traversal (..) is not allowed in ${scheme}:// URLs: ${r
- Destination paths cannot contain parent traversal or NUL byt
- Shared-folder destination escapes its configured root
- ${scheme}:// path escapes its root: ${rawPath}
- Unsafe #{scheme}:// path (absolute or traversal): #{path}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/55615a805e4dba59.
Report an issue: GitHub.