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

  1. Use the exact argument name from the tool's advertised inputSchema (check `tools/list` output).
  2. Follow the 'Did you mean' suggestion in the error message — it maps the unknown key to the closest valid one.
  3. Fold known numeric aliases onto canonical keys before calling (e.g. `depth` → `maxDepth`); conflicting alias values must be resolved to one.
  4. 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

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


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)