can1357/oh-my-pi · error
Host tool at index ${index} must provide a non-empty name
Error message
Host tool at index ${index} must provide a non-empty name What it means
normalizeHostToolDefinitions validates each host-provided tool before registering it with the agent. The tool's name must be a string that is non-empty after trimming; otherwise this error is thrown with the tool's array index. It ensures every host tool has an identifier usable for dispatch.
Source
Thrown at packages/coding-agent/src/modes/rpc/rpc-mode.ts:501
const cancelled = !(await session.switchSession(command.sessionPath));
if (!cancelled) subagentRegistry?.clear();
return { type: "switch_session", data: { cancelled } };
}
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),
};
});View on GitHub (pinned to 9690622007)
Solutions
- Set a non-empty 'name' string on the tool entry at the reported index.
- If names are generated, validate/trim them before passing the array and drop or repair entries with empty names.
- Fix config key casing so the name field is actually read (e.g. 'name' not 'Name').
Example fix
// before
const tools = [{ description: "Run a shell command", parameters: { type: "object" } }];
// after
const tools = [{ name: "run_shell", description: "Run a shell command", parameters: { type: "object" } }]; Defensive patterns
Strategy: validation
Validate before calling
tools.forEach((t, i) => {
if (typeof t.name !== "string" || !t.name.trim()) throw new Error(`Tool at index ${i} missing non-empty name`);
}); Type guard
function hasValidName(t: { name: unknown }): t is { name: string } {
return typeof t.name === "string" && t.name.trim().length > 0;
} Try / catch
try {
rpc.registerHostTools(tools);
} catch (err) {
if (err instanceof Error && /must provide a non-empty name/.test(err.message)) {
logger.warn("skipping host tool with empty name", { err });
} else throw err;
} Prevention
- Build tool definitions from a typed interface with a required name field so TS catches omissions.
- Trim and validate names at the point where tool metadata is generated.
- Watch for casing mismatches ('Name' vs 'name') when loading tools from JSON config.
When it happens
Trigger: Registering host tools via the tools option with an entry whose name is undefined, an empty string, whitespace-only, or a non-string (e.g. a number or null).
Common situations: Programmatic tool list generation where one entry's name field is omitted or built from an empty variable; JSON configs where 'name' was misspelled so it defaults to undefined.
Related errors
- Host tool "${name}" must provide a non-empty description
- Host tool "${name}" must provide a JSON Schema object
- RPC host tool names must be unique
- Unsupported language '{value}'. Supported: {}
- Unable to infer language from file extension: {}. Specify `l
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/7add6217c772ed7c.
Report an issue: GitHub.