{"record":{"id":"bf977ad3529de601","repo":"can1357/oh-my-pi","slug":"unknown-uri-like-write-target-trimmed-sugge","errorCode":null,"errorMessage":"Unknown URI-like write target '${trimmed}'.${suggestion} Prefix the path with './' to write it as a filesystem path.","messagePattern":"Unknown URI-like write target '(.+?)'\\.(.+?) Prefix the path with '\\./' to write it as a filesystem path\\.","errorType":"validation","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/write.ts","lineNumber":136,"sourceCode":"\tconst missingDelimiter = trimmed.match(XD_MISSING_DELIMITER_RE);\n\tif (missingDelimiter) {\n\t\tthrow new ToolError(\n\t\t\t`Unknown URI-like write target '${trimmed}'. Did you mean 'xd://${missingDelimiter[1]}'? Prefix the path with './' to write it as a filesystem path.`,\n\t\t);\n\t}\n\n\tconst uriLike = trimmed.match(URI_LIKE_WRITE_PATH_RE);\n\tif (!uriLike) return;\n\n\tconst scheme = uriLike[1]!.toLowerCase();\n\t// conflict:// has no router handler but is spliced downstream by\n\t// parseConflictUri (which emits its own precise id/scope errors); let it pass.\n\tif (scheme === \"conflict\") return;\n\tconst canonicalScheme = router.getHandler(scheme) ? scheme : XD_SCHEME_NEAR_MISSES[scheme] ? \"xd\" : undefined;\n\tconst suggestion = canonicalScheme\n\t\t? ` Did you mean '${canonicalScheme}://${uriLike[2]}'?`\n\t\t: \" Tool devices use 'xd://<tool>'.\";\n\tthrow new ToolError(\n\t\t`Unknown URI-like write target '${trimmed}'.${suggestion} Prefix the path with './' to write it as a filesystem path.`,\n\t);\n}\n\n/**\n * Fail closed when a local write target looks like a mis-dispatched read.\n *\n * A read-only step that selects `write` instead of `read` passes the full read\n * expression (`src/foo.tsx:1-260:raw`) as the target. Because a literal colon\n * filename is legal on POSIX (issue #4618), that request otherwise resolves to\n * filesystem creation and reports success, leaving a stray zero-byte file the\n * model cannot recover from — the local analogue of the `xd://` near-miss guard\n * ({@link assertWriteTargetAddressable}, issue #6123).\n *\n * Fires only on the high-confidence combination the report identifies: the tail\n * parses as a read-tool selector, the literal target is missing, and no content\n * was supplied. Non-empty content is the escape hatch — it is never blocked, so\n * a deliberate write to a selector-shaped filename still succeeds. An existing","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/write.ts#L118-L154","documentation":"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>'.","triggerScenarios":"write({ path: \"unknown-scheme://thing\", content }) where the scheme has no registered handler and is not 'conflict' or an xd near-miss.","commonSituations":"Typos in scheme names (xdz://, xdd://), inventing schemes the router does not know, mixing up read-only scheme names with writable ones.","solutions":["Correct the scheme to the suggested canonical one (e.g. 'xd://<tool>')","Use 'xd://<tool>' if you intended a tool device target","Prefix the target with './' if it is meant to be a literal filesystem path"],"exampleFix":"// before\nwrite({ path: \"xdz://mem-1\", content: \"...\" })\n// after\nwrite({ path: \"xd://mem-1\", content: \"...\" })","handlingStrategy":"validation","validationCode":"const KNOWN = new Set([\"xd\", \"conflict\"]);\nfunction validateScheme(target: string): string | null {\n  const m = target.trim().match(/^([a-z][a-z0-9+.-]*):\\/\\//i);\n  if (!m) return null;\n  const scheme = m[1].toLowerCase();\n  return KNOWN.has(scheme) ? null : scheme;\n}","typeGuard":"function hasKnownScheme(t: string, router: Router): boolean {\n  const m = t.trim().match(/^([a-z][a-z0-9+.-]*):\\/\\//i);\n  return !m || !!router.getHandler(m[1].toLowerCase());\n}","tryCatchPattern":"try {\n  await write({ path: target, content });\n} catch (e) {\n  if (e instanceof ToolError && e.message.includes(\"Unknown URI-like write target\")) {\n    const m = e.message.match(/Did you mean '([^']+)'/);\n    if (m) return write({ path: m[1], content });\n  }\n  throw e;\n}","preventionTips":["Only use schemes registered with the URL router (xd://, conflict://)","Do not invent custom schemes for write targets","Check the scheme near-miss list when unsure of exact spelling"],"tags":["path-validation","uri","unknown-scheme"],"backgroundTag":"unknown-uri-scheme","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}