can1357/oh-my-pi · error · ToolError

Unknown URI-like write target '${trimmed}'.${suggestion} Pre

Error message

Unknown URI-like write target '${trimmed}'.${suggestion} Prefix the path with './' to write it as a filesystem path.

What it means

Same guard as the missing-delimiter case, but for targets whose scheme does not resolve to a router handler and is not a known near-miss of the 'xd' scheme (or an intentional 'conflict' pass-through). The tool cannot route the target and throws with a scheme suggestion or a pointer to 'xd://<tool>'.

Source

Thrown at packages/coding-agent/src/tools/write.ts:136

	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.`,
	);
}

/**
 * Fail closed when a local write target looks like a mis-dispatched read.
 *
 * A read-only step that selects `write` instead of `read` passes the full read
 * expression (`src/foo.tsx:1-260:raw`) as the target. Because a literal colon
 * filename is legal on POSIX (issue #4618), that request otherwise resolves to
 * filesystem creation and reports success, leaving a stray zero-byte file the
 * model cannot recover from — the local analogue of the `xd://` near-miss guard
 * ({@link assertWriteTargetAddressable}, issue #6123).
 *
 * Fires only on the high-confidence combination the report identifies: the tail
 * parses as a read-tool selector, the literal target is missing, and no content
 * was supplied. Non-empty content is the escape hatch — it is never blocked, so
 * a deliberate write to a selector-shaped filename still succeeds. An existing

View on GitHub (pinned to 9690622007)

Solutions

  1. Correct the scheme to the suggested canonical one (e.g. 'xd://<tool>')
  2. Use 'xd://<tool>' if you intended a tool device target
  3. Prefix the target with './' if it is meant to be a literal filesystem path

Example fix

// before
write({ path: "xdz://mem-1", content: "..." })
// after
write({ path: "xd://mem-1", content: "..." })
Defensive patterns

Strategy: validation

Validate before calling

const KNOWN = new Set(["xd", "conflict"]);
function validateScheme(target: string): string | null {
  const m = target.trim().match(/^([a-z][a-z0-9+.-]*):\/\//i);
  if (!m) return null;
  const scheme = m[1].toLowerCase();
  return KNOWN.has(scheme) ? null : scheme;
}

Type guard

function hasKnownScheme(t: string, router: Router): boolean {
  const m = t.trim().match(/^([a-z][a-z0-9+.-]*):\/\//i);
  return !m || !!router.getHandler(m[1].toLowerCase());
}

Try / catch

try {
  await write({ path: target, content });
} catch (e) {
  if (e instanceof ToolError && e.message.includes("Unknown URI-like write target")) {
    const m = e.message.match(/Did you mean '([^']+)'/);
    if (m) return write({ path: m[1], content });
  }
  throw e;
}

Prevention

When it happens

Trigger: write({ path: "unknown-scheme://thing", content }) where the scheme has no registered handler and is not 'conflict' or an xd near-miss.

Common situations: Typos in scheme names (xdz://, xdd://), inventing schemes the router does not know, mixing up read-only scheme names with writable ones.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/bf977ad3529de601. Report an issue: GitHub.