{"record":{"id":"ad2d349a850230e0","repo":"can1357/oh-my-pi","slug":"host-tool-name-must-provide-a-json-schema-obj","errorCode":null,"errorMessage":"Host tool \"${name}\" must provide a JSON Schema object","messagePattern":"Host tool \"(.+?)\" must provide a JSON Schema object","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/modes/rpc/rpc-mode.ts","lineNumber":508,"sourceCode":"\t\t\tif (!result.cancelled) subagentRegistry?.clear();\n\t\t\treturn { type: \"branch\", data: { text: result.selectedText, cancelled: result.cancelled } };\n\t\t}\n\t}\n\tthrow new Error(\"Unsupported RPC session change command\");\n}\n\nfunction normalizeHostToolDefinitions(tools: RpcHostToolDefinition[]): RpcHostToolDefinition[] {\n\treturn tools.map((tool, index) => {\n\t\tconst name = typeof tool.name === \"string\" ? tool.name.trim() : \"\";\n\t\tif (!name) {\n\t\t\tthrow new Error(`Host tool at index ${index} must provide a non-empty name`);\n\t\t}\n\t\tconst description = typeof tool.description === \"string\" ? tool.description.trim() : \"\";\n\t\tif (!description) {\n\t\t\tthrow new Error(`Host tool \"${name}\" must provide a non-empty description`);\n\t\t}\n\t\tif (!tool.parameters || typeof tool.parameters !== \"object\" || Array.isArray(tool.parameters)) {\n\t\t\tthrow new Error(`Host tool \"${name}\" must provide a JSON Schema object`);\n\t\t}\n\t\tconst label = typeof tool.label === \"string\" && tool.label.trim() ? tool.label.trim() : name;\n\t\treturn {\n\t\t\tname,\n\t\t\tlabel,\n\t\t\tdescription,\n\t\t\tparameters: tool.parameters,\n\t\t\thidden: tool.hidden === true,\n\t\t\tloadMode: defaultLoadModeForToolName(name, tool.loadMode),\n\t\t};\n\t});\n}\n\nfunction parseValueDialogResponse(\n\tresponse: RpcExtensionUIResponse,\n\tdialogOptions: ExtensionUIDialogOptions | undefined,\n): string | undefined {\n\tif (\"cancelled\" in response && response.cancelled) {","sourceCodeStart":490,"sourceCodeEnd":526,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/modes/rpc/rpc-mode.ts#L490-L526","documentation":"normalizeHostToolDefinitions requires each host tool's 'parameters' to be a JSON Schema object: it must be present, be a plain object (not an array), and describe the tool's input schema. Anything else (missing, null, an array, a string) throws this error naming the tool.","triggerScenarios":"Registering a host tool where parameters is omitted, null, an array, a JSON string of the schema (not a parsed object), or some other non-object value.","commonSituations":"Passing a schema that was serialized with JSON.stringify instead of kept as an object; configs where the schema lives under a different key so 'parameters' is undefined; tools with no arguments defined at all.","solutions":["Supply parameters as a JSON Schema object; for a tool with no arguments use { type: \"object\", properties: {} }.","If the schema is stored as a JSON string, JSON.parse it before registration.","Move/alias the schema key so it lands in 'parameters' when loading from external config."],"exampleFix":"// before\n{ name: \"run_shell\", description: \"...\", parameters: JSON.stringify({ type: \"object\", properties: { cmd: { type: \"string\" } } }) }\n// after\n{ name: \"run_shell\", description: \"...\", parameters: { type: \"object\", properties: { cmd: { type: \"string\" } }, required: [\"cmd\"] } }","handlingStrategy":"validation","validationCode":"function isJsonSchemaObject(v: unknown): boolean {\n  return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\nif (!tools.every(t => isJsonSchemaObject(t.parameters))) throw new Error(\"all tools need a JSON Schema object for parameters\");","typeGuard":"function isJsonSchemaObject(v: unknown): v is Record<string, unknown> {\n  return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}","tryCatchPattern":"try {\n  rpc.registerHostTools(tools);\n} catch (err) {\n  if (err instanceof Error && /JSON Schema object/.test(err.message)) {\n    logger.warn(\"host tool has invalid parameters schema\", { err });\n  } else throw err;\n}","preventionTips":["Keep schemas as objects end-to-end; JSON.stringify them only for wire transport that re-parses, never for registration.","For no-argument tools use { type: \"object\", properties: {} } rather than omitting parameters.","Lint tool configs for the presence of the 'parameters' key."],"tags":["validation","json-schema","rpc","tools"],"backgroundTag":"tool-definition-validation","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}