can1357/oh-my-pi · error

Host tool "${name}" must provide a JSON Schema object

Error message

Host tool "${name}" must provide a JSON Schema object

What it means

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.

Source

Thrown at packages/coding-agent/src/modes/rpc/rpc-mode.ts:508

			if (!result.cancelled) subagentRegistry?.clear();
			return { type: "branch", data: { text: result.selectedText, cancelled: result.cancelled } };
		}
	}
	throw new Error("Unsupported RPC session change command");
}

function normalizeHostToolDefinitions(tools: RpcHostToolDefinition[]): RpcHostToolDefinition[] {
	return tools.map((tool, index) => {
		const name = typeof tool.name === "string" ? tool.name.trim() : "";
		if (!name) {
			throw new Error(`Host tool at index ${index} must provide a non-empty name`);
		}
		const description = typeof tool.description === "string" ? tool.description.trim() : "";
		if (!description) {
			throw new Error(`Host tool "${name}" must provide a non-empty description`);
		}
		if (!tool.parameters || typeof tool.parameters !== "object" || Array.isArray(tool.parameters)) {
			throw new Error(`Host tool "${name}" must provide a JSON Schema object`);
		}
		const label = typeof tool.label === "string" && tool.label.trim() ? tool.label.trim() : name;
		return {
			name,
			label,
			description,
			parameters: tool.parameters,
			hidden: tool.hidden === true,
			loadMode: defaultLoadModeForToolName(name, tool.loadMode),
		};
	});
}

function parseValueDialogResponse(
	response: RpcExtensionUIResponse,
	dialogOptions: ExtensionUIDialogOptions | undefined,
): string | undefined {
	if ("cancelled" in response && response.cancelled) {

View on GitHub (pinned to 9690622007)

Solutions

  1. Supply parameters as a JSON Schema object; for a tool with no arguments use { type: "object", properties: {} }.
  2. If the schema is stored as a JSON string, JSON.parse it before registration.
  3. Move/alias the schema key so it lands in 'parameters' when loading from external config.

Example fix

// before
{ name: "run_shell", description: "...", parameters: JSON.stringify({ type: "object", properties: { cmd: { type: "string" } } }) }
// after
{ name: "run_shell", description: "...", parameters: { type: "object", properties: { cmd: { type: "string" } }, required: ["cmd"] } }
Defensive patterns

Strategy: validation

Validate before calling

function isJsonSchemaObject(v: unknown): boolean {
  return typeof v === "object" && v !== null && !Array.isArray(v);
}
if (!tools.every(t => isJsonSchemaObject(t.parameters))) throw new Error("all tools need a JSON Schema object for parameters");

Type guard

function isJsonSchemaObject(v: unknown): v is Record<string, unknown> {
  return typeof v === "object" && v !== null && !Array.isArray(v);
}

Try / catch

try {
  rpc.registerHostTools(tools);
} catch (err) {
  if (err instanceof Error && /JSON Schema object/.test(err.message)) {
    logger.warn("host tool has invalid parameters schema", { err });
  } else throw err;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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