abhigyanpatwari/GitNexus · error
Unknown for tool " ". "?` : ` The advertised inputSchema…
Error message
Unknown ${noun} ${quoted} for tool "${toolName}".${suggestion ? ` Did you mean "${suggestion}"?` : ` The advertised inputSchema ${verb} not include ${unknownKeys.length === 1 ? 'this key' : 'these keys'}.`}" What it means
The MCP server validates every tool call's top-level arguments against the tool's advertised inputSchema plus a small set of unpublished aliases. If the caller passes keys that are neither advertised nor aliased, `assertKnownMcpToolArguments` throws immediately with the unknown key names, a fuzzy 'Did you mean' suggestion when one matches, or a note that the advertised schema does not include the keys.
Solutions
- Use the exact argument name from the tool's advertised inputSchema (check `tools/list` output).
- Follow the 'Did you mean' suggestion in the error message — it maps the unknown key to the closest valid one.
- Fold known numeric aliases onto canonical keys before calling (e.g. `depth` → `maxDepth`); conflicting alias values must be resolved to one.
- If arguments were valid before an upgrade, refresh the MCP client's cached tool schemas to the current server version.
Example fix
// before
{ "tool": "impact", "args": { "target": "foo", "dept": 2 } }
// after (error suggests "maxDepth"; depth is an accepted alias)
{ "tool": "impact", "args": { "target": "foo", "maxDepth": 2 } } Defensive patterns
Strategy: validation
Validate before calling
// validate tool args against the advertised schema before calling
function validateToolArgs(toolName, args, advertisedProperties) {
const allowed = new Set(Object.keys(advertisedProperties));
const unknown = Object.keys(args).filter(k => !allowed.has(k));
if (unknown.length) throw new Error(`Unknown argument(s) ${unknown.join(', ')} for tool "${toolName}"`);
} Type guard
const isKnownToolArg = (toolName, key, advertisedProperties) => key in advertisedProperties; // or consult tools/list schemas cached from the server
Try / catch
try {
const res = await mcpClient.callTool(toolName, args);
} catch (e) {
const m = /Did you mean "([^"]+)"\?/.exec(e.message);
if (m) return callTool(toolName, { ...args, [m[1]]: args[unknownKey] });
throw e;
} Prevention
- Generate client call sites from the server's `tools/list` schema instead of hand-writing argument names.
- Use canonical argument names (e.g. `maxDepth`), not aliases, in persistent configs.
- After upgrading GitNexus, refresh cached tool schemas in the MCP client.
- Keep an integration test that calls each tool with valid args to catch renames early.
When it happens
Trigger: An MCP client invokes a GitNexus tool (e.g. `impact`, `query`, `analyze`) with a misspelled argument (`dept` instead of `depth`), a snake_case variant, an argument that exists on a different GitNexus tool, or an argument removed/renamed in a newer GitNexus version while the client config still sends the old name.
Common situations: Hand-edited MCP client configs with stale or mistyped argument names; copy-pasting arguments between tools; using camelCase vs snake_case inconsistently; a GitNexus upgrade renaming arguments while an agent's cached tool descriptions are stale.
Related errors
- must not be blank.
- must not be blank.
- must be a positive integer
- GITNEXUS_MCP_READ_ONLY must be 0 or 1.
- must be a positive integer.
AI-assisted analysis of abhigyanpatwari/GitNexus@ac9a4e9abd (2026-09-15).
Data as JSON: /api/errors/59f0c71cadd77109.
Report an issue: GitHub.
Appendix: source
Thrown at gitnexus/src/mcp/tool-arguments.ts:125
toolName: string,
args: Record<string, unknown> | undefined,
advertisedProperties?: Record<string, unknown>,
): void {
if (!args) return;
const propertyNames =
advertisedProperties !== undefined
? Object.keys(advertisedProperties)
: advertisedToolPropertyNames(toolName);
if (!propertyNames) return;
const unpublished =
UNPUBLISHED_TOOL_ARGUMENT_ALIASES[toolName] ??
UNPUBLISHED_TOOL_ARGUMENT_ALIASES[schemaSourceToolName(toolName)] ??
[];
const allowed = new Set([...propertyNames, ...unpublished]);
const unknownKeys = Object.keys(args).filter((key) => !allowed.has(key));
if (unknownKeys.length === 0) return;
throw new Error(formatUnknownArgumentError(toolName, unknownKeys, propertyNames));
}
/**
* Fold numeric aliases onto their canonical key (e.g. `depth` → `maxDepth`).
* Conflicting values error; a single agreed value is written to the canonical
* key and the alias keys are removed so every downstream reader sees one name.
*/
export function foldNumericToolArgumentAliases(
toolName: string,
params: Record<string, unknown>,
): { params: Record<string, unknown> } | { error: string } {
const definitions = TOOL_NUMERIC_ARGUMENT_ALIASES[toolName];
if (!definitions) return { params };
const normalized = { ...params };
for (const { canonical, aliases } of definitions) {
const keys = [canonical, ...aliases];
const supplied: Array<{ key: string; value: number }> = [];View on GitHub (pinned to ac9a4e9abd)