can1357/oh-my-pi · error

Host tool "${name}" must provide a non-empty description

Error message

Host tool "${name}" must provide a non-empty description

What it means

normalizeHostToolDefinitions requires every host tool to carry a non-empty description: the value must be a string with content after trimming. Descriptions are sent to the LLM so it can decide when to call the tool; an empty one would degrade tool use, so the registration is rejected with this error naming the offending tool.

Source

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

		case "branch": {
			const result = await session.branch(command.entryId);
			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,

View on GitHub (pinned to 9690622007)

Solutions

  1. Provide a concise, meaningful 'description' string for the named tool.
  2. If descriptions come from a data source, add a fallback that substitutes a generated description before registration.
  3. Validate tool metadata (name, description, parameters) at the boundary before calling the RPC host-tool registration.

Example fix

// before
{ name: "run_shell", description: "", parameters: { type: "object" } }
// after
{ name: "run_shell", description: "Execute a shell command in the workspace and return its output", parameters: { type: "object" } }
Defensive patterns

Strategy: validation

Validate before calling

for (const t of tools) {
  if (typeof t.description !== "string" || !t.description.trim()) throw new Error(`Tool ${t.name} missing description`);
}

Type guard

function hasValidDescription(t: { description: unknown }): t is { description: string } {
  return typeof t.description === "string" && t.description.trim().length > 0;
}

Try / catch

try {
  rpc.registerHostTools(tools);
} catch (err) {
  if (err instanceof Error && /non-empty description/.test(err.message)) {
    logger.warn("host tool missing description", { err });
  } else throw err;
}

Prevention

When it happens

Trigger: Registering a host tool whose description is missing, an empty string, or whitespace-only (e.g. description: "" or a template that resolved to empty).

Common situations: Tool metadata generated from another source where the description field is optional upstream; hand-written tool configs that skip the description for 'obvious' tools.

Related errors


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