{"record":{"id":"ee3d60c661612fb3","repo":"can1357/oh-my-pi","slug":"cannot-write-to-xd-itself-pick-a-device-n-x","errorCode":null,"errorMessage":"Cannot write to xd:// itself — pick a device:\\n${xdevListing(xdev)}","messagePattern":"Cannot write to xd:// itself — pick a device:\\\\n(.+?)","errorType":"validation","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/write.ts","lineNumber":1183,"sourceCode":"\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (name && isResolutionDeviceName(name)) {\n\t\t\t\t\t\t\t\t\tconst { result, xdev } = await dispatchResolutionDevice(this.session, name, deviceContent);\n\t\t\t\t\t\t\t\t\txdResult = {\n\t\t\t\t\t\t\t\t\t\tcontent: result.content,\n\t\t\t\t\t\t\t\t\t\tdetails: { xdev },\n\t\t\t\t\t\t\t\t\t\tisError: result.isError,\n\t\t\t\t\t\t\t\t\t\tuseless: result.useless,\n\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tconst xdev = this.session.xdev;\n\t\t\t\t\t\t\t\tif (!xdev) {\n\t\t\t\t\t\t\t\t\tthrow new ToolError(\"xd:// is not mounted in this session.\");\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (!name) {\n\t\t\t\t\t\t\t\t\tthrow new ToolError(`Cannot write to xd:// itself — pick a device:\\n${xdevListing(xdev)}`);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tconst { result, xdev: dispatch } = await dispatchXdevTool(\n\t\t\t\t\t\t\t\t\txdev,\n\t\t\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\t\t\tdeviceContent,\n\t\t\t\t\t\t\t\t\t_toolCallId,\n\t\t\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t\t\t\tonUpdate as AgentToolUpdateCallback,\n\t\t\t\t\t\t\t\t\t// The write tool's own gate just resolved approval at this\n\t\t\t\t\t\t\t\t\t// device's tier (see #approval above) — mark it so a wrapped\n\t\t\t\t\t\t\t\t\t// inner tool does not prompt a second time.\n\t\t\t\t\t\t\t\t\tcontext ? { ...context, xdevApproved: true } : undefined,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\txdResult = {\n\t\t\t\t\t\t\t\t\tcontent: result.content,\n\t\t\t\t\t\t\t\t\tdetails: { xdev: dispatch },\n\t\t\t\t\t\t\t\t\tisError: result.isError,\n\t\t\t\t\t\t\t\t\tuseless: result.useless,","sourceCodeStart":1165,"sourceCodeEnd":1201,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/write.ts#L1165-L1201","documentation":"WriteTool supports special internal URLs like xd:// in place of a normal file path. Writing to the bare `xd://` URL has no meaning — xd:// is a device namespace, so the tool requires a device name (`xd://<device>`). It throws this ToolError and prints a listing of the mounted xdev devices so the caller can pick one.","triggerScenarios":"Calling the Write tool with path exactly `xd://` (no device name) while xdev is mounted in the session; typically when the model abbreviates an intended `xd://<device>` target.","commonSituations":"An LLM agent emits `xd://` as a shorthand target when composing a write, or truncates the device name from a previously successful xd:// call.","solutions":["Append the target device name: write to `xd://<device>` instead of `xd://`.","Check the device list printed in the error message (from xdevListing) and use one of the listed names.","Use the session's mounted xd:// devices or a regular filesystem path if no xdev device is intended.","If no device is needed at all, write to a normal file path instead of an xd:// URL."],"exampleFix":"// before\nwrite({ path: \"xd://\", content: \"...\" })\n// after\nwrite({ path: \"xd://browser\", content: \"...\" })","handlingStrategy":"validation","validationCode":"if (path === \"xd://\" || path === \"xd:///\") throw new Error(\"Pick a device: use xd://<device>, e.g. xd://browser\");","typeGuard":"function isBareXdevRoot(path: string): boolean { return path.replace(/\\/$/, \"\") === \"xd://\"; }","tryCatchPattern":"try { await write({ path, content }); } catch (e) { if (String(e.message).startsWith(\"Cannot write to xd:// itself\")) { const devices = e.message.split(\"\\n\").slice(1); /* retry with a listed device */ } else throw e; }","preventionTips":["Never target the bare xd:// root; always include a device name.","Keep the device listing from the error and choose from it.","For plain files, use normal filesystem paths instead of xd://.","Validate URL scheme+authority before dispatching writes."],"tags":["tool-error","xdev","invalid-path"],"backgroundTag":"invalid-device-uri","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}