{"record":{"id":"5bd602d6e309148f","repo":"can1357/oh-my-pi","slug":"xd-url-prefix-device-name-expects-a-json-args","errorCode":null,"errorMessage":"${XD_URL_PREFIX}${device.name} expects a JSON args object as content (${error instanceof Error ? error.message : String(error)}). Write `?` for docs.","messagePattern":"(.+?)(.+?) expects a JSON args object as content \\((.+?)\\)\\. Write `\\?` for docs\\.","errorType":"validation","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/xdev.ts","lineNumber":159,"sourceCode":"}\n\n/**\n * Parse and validate a device write's JSON `content` against the wrapped\n * tool's wire schema. Strips a habitual top-level `i` (intent) unless the\n * schema declares one. Throws ToolError; schema-mismatch errors carry `docs()`\n * for repair.\n */\nfunction parseDeviceArgs(\n\tdevice: AiTool,\n\tcontent: string,\n\ttoolCallId: string,\n\tdocs: () => string,\n): Record<string, unknown> {\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(content);\n\t} catch (error) {\n\t\tthrow new ToolError(\n\t\t\t`${XD_URL_PREFIX}${device.name} expects a JSON args object as content (${error instanceof Error ? error.message : String(error)}). Write \\`?\\` for docs.`,\n\t\t);\n\t}\n\tif (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\tthrow new ToolError(\n\t\t\t`${XD_URL_PREFIX}${device.name} content must be a JSON object, got ${Array.isArray(parsed) ? \"array\" : typeof parsed}.`,\n\t\t);\n\t}\n\t// The harness only injects the intent field into top-level schemas; strip a\n\t// habitual `i` from inner args unless the wrapped schema really declares it.\n\tconst args: Record<string, unknown> = { ...(parsed as Record<string, unknown>) };\n\tif (\"i\" in args && !schemaDeclaresIntentField(toolWireSchema(device))) delete args.i;\n\ttry {\n\t\treturn validateToolArguments(device, {\n\t\t\ttype: \"toolCall\",\n\t\t\tid: toolCallId,\n\t\t\tname: device.name,\n\t\t\targuments: args,","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/xdev.ts#L141-L177","documentation":"xd:// devices take their arguments as a JSON object carried in the write `content`. parseDeviceArgs runs JSON.parse on the content, and if it is not valid JSON it throws this ToolError naming the device, the JSON parse error, and a hint to write `?` as content to fetch the device's docs.","triggerScenarios":"Calling Write to `xd://<device>` with content that is not parseable JSON — e.g. plain prose, a shell-style flag string, trailing commas, single quotes, or markdown wrapping the JSON.","commonSituations":"An agent writes natural-language instructions or key=value text to an xd:// device instead of a JSON object; or the JSON got mangled by escaping/quoting issues.","solutions":["Send the arguments as a valid JSON object, e.g. {\"key\": \"value\"}.","Write `?` as content to `xd://<device>` to retrieve the device's docs and schema.","Validate the content with JSON.parse (or a linter) before the write.","Remove non-JSON decoration: no comments, trailing commas, single quotes, or surrounding prose."],"exampleFix":"// before\nwrite({ path: \"xd://browser\", content: \"navigate to example.com\" })\n// after\nwrite({ path: \"xd://browser\", content: \"{\\\"action\\\":\\\"navigate\\\",\\\"url\\\":\\\"https://example.com\\\"}\" })","handlingStrategy":"validation","validationCode":"try { JSON.parse(content); } catch (err) { throw new Error(`xd:// content must be valid JSON: ${err.message}`); }","typeGuard":"function isJsonString(s: string): boolean { try { JSON.parse(s); return true; } catch { return false; } }","tryCatchPattern":"try { await write({ path: `xd://${device}`, content }); } catch (e) { if (String(e.message).includes(\"expects a JSON args object\")) { const docs = await write({ path: `xd://${device}`, content: \"?\" }); /* rebuild JSON args from docs */ } else throw e; }","preventionTips":["Always JSON.stringify the args object before writing to xd:// devices.","Write `?` as content first to learn the device's schema.","Strip comments/trailing commas that break strict JSON.parse.","Avoid free-text prose in xd:// content."],"tags":["json","tool-error","xdev"],"backgroundTag":"invalid-json-args","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}