can1357/oh-my-pi · error · ToolError
Unknown URI-like write target '${trimmed}'. Did you mean 'xd
Error message
Unknown URI-like write target '${trimmed}'. Did you mean 'xd://${missingDelimiter[1]}'? Prefix the path with './' to write it as a filesystem path. What it means
The write tool validates that its target path is either an absolute filesystem path or a routable URL. If the target looks like a URI but the scheme is missing the '//' after a colon (e.g. 'xd:foo' instead of 'xd://foo'), the tool refuses to guess and throws, telling you the exact corrected form. This exists to prevent silently creating a literal file named like a URI.
Source
Thrown at packages/coding-agent/src/tools/write.ts:120
resolveXdevTool,
type XdevDispatch,
xdevActivitySummary,
xdevListing,
} from "./xdev";
const LOOSE_HASHLINE_HEADER_RE = /^\s*\[[^#\r\n]+#[^ \t\r\n]*\]\s*$/;
const EXECUTABLE_NOTICE = "[Notice: Made executable via chmod +x]";
const URI_LIKE_WRITE_PATH_RE = /^([a-z][a-z0-9+.-]*):\/{1,2}(.*)$/i;
const XD_MISSING_DELIMITER_RE = /^xd\/+(.*)$/i;
const XD_SCHEME_NEAR_MISSES: Record<string, true> = { dx: true, xdd: true, xdt: true };
function assertWriteTargetAddressable(target: string, router: InternalUrlRouter): void {
const trimmed = target.trim();
if (path.win32.isAbsolute(trimmed) || router.canHandle(trimmed)) return;
const missingDelimiter = trimmed.match(XD_MISSING_DELIMITER_RE);
if (missingDelimiter) {
throw new ToolError(
`Unknown URI-like write target '${trimmed}'. Did you mean 'xd://${missingDelimiter[1]}'? Prefix the path with './' to write it as a filesystem path.`,
);
}
const uriLike = trimmed.match(URI_LIKE_WRITE_PATH_RE);
if (!uriLike) return;
const scheme = uriLike[1]!.toLowerCase();
// conflict:// has no router handler but is spliced downstream by
// parseConflictUri (which emits its own precise id/scope errors); let it pass.
if (scheme === "conflict") return;
const canonicalScheme = router.getHandler(scheme) ? scheme : XD_SCHEME_NEAR_MISSES[scheme] ? "xd" : undefined;
const suggestion = canonicalScheme
? ` Did you mean '${canonicalScheme}://${uriLike[2]}'?`
: " Tool devices use 'xd://<tool>'.";
throw new ToolError(
`Unknown URI-like write target '${trimmed}'.${suggestion} Prefix the path with './' to write it as a filesystem path.`,
);View on GitHub (pinned to 9690622007)
Solutions
- Add the missing '//' after the scheme: write 'xd://<tool>' instead of 'xd:<tool>'
- If you actually want a literal filesystem file, prefix the path with './' so it is treated as a relative path
Example fix
// before
write({ path: "xd:mem-1", content: "..." })
// after
write({ path: "xd://mem-1", content: "..." }) Defensive patterns
Strategy: validation
Validate before calling
const XD_MISSING_DELIMITER_RE = /^([a-z][a-z0-9+.-]*):(?![\/\/])(.+)/i;
function isWriteTargetAddressable(target: string, router: { canHandle(t: string): boolean }): boolean {
const t = target.trim();
if (path.win32.isAbsolute(t) || router.canHandle(t)) return true;
return !XD_MISSING_DELIMITER_RE.test(t);
}
if (!isWriteTargetAddressable(p, router)) p = p.replace(/^([a-z][a-z0-9+.-]*):/i, "$1://"); Type guard
function isRoutableTarget(t: string, router: Router): boolean {
return router.canHandle(t.trim()) || path.win32.isAbsolute(t.trim());
} Try / catch
try {
await write({ path: target, content });
} catch (e) {
if (e instanceof ToolError && e.message.includes("Unknown URI-like write target")) {
target = target.replace(/^([a-z][a-z0-9+.-]*):(?!\/\/)/i, "$1://");
return write({ path: target, content });
}
throw e;
} Prevention
- Always use the full scheme form scheme:// for tool-device targets
- Prefix literal relative paths with ./ when they might look URI-like
- Validate targets against the router before calling write
When it happens
Trigger: Calling write({ path: "xd:conflict-1" }) or any target matching a scheme-without-delimiter pattern like 'scheme:rest' that is not win32-absolute and not router-handled.
Common situations: Models or scripts omitting the '//' in custom scheme URLs (xd:, conflict:) when writing; pasting URIs from docs that dropped slashes.
Related errors
- Unknown URI-like write target '${trimmed}'.${suggestion} Pre
- invalid template, {}, contains directory separator
- invalid suffix {}, contains directory separator
- ${error.message} (rethrown as ToolError from StructuredSubag
- git-subdir path "${source.path}" does not exist in cloned re
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/636ead282e59587c.
Report an issue: GitHub.