abhigyanpatwari/GitNexus · error

Unknown group tool: ${method}. Removed tools: use repo "@<gr

Error message

Unknown group tool: ${method}. Removed tools: use repo "@<groupName>" on impact, query, or context (optional "/<memberPath>"), or MCP resources.

What it means

handleGroupTool only recognizes group_list and group_sync; anything else in the group namespace throws, and since v1.5.0 removed group_query/group_contracts/group_status, the message actively redirects: use repo "@<groupName>" (optionally "/<memberPath>") on impact, query, or context, or the gitnexus://group/{name} MCP resources.

Source

Thrown at gitnexus/src/mcp/local/local-backend.ts:8202

        // Group cross-repo fan-out consumes only byDepth (cross-impact.ts), not
        // the #1858 epistemic/boundaries fields — computing them per neighbor is
        // dead work on the highest-volume path, so suppress them here too.
        skipEpistemic: true,
        hasExplicitRelationTypes: opts.relationTypes.length > 0,
      });
    } catch {
      return null;
    }
  }

  private handleGroupTool(method: string, params: Record<string, unknown>): Promise<unknown> {
    switch (method) {
      case 'group_list':
        return this.groupList(params);
      case 'group_sync':
        return this.groupSync(params);
      default:
        throw new Error(
          `Unknown group tool: ${method}. Removed tools: use repo "@<groupName>" on impact, query, or context (optional "/<memberPath>"), or MCP resources.`,
        );
    }
  }

  /**
   * Dispatch impact/query/context when `repo` is `@groupName` or `@groupName/memberPath`
   * (group mode — not the global indexed-repo `repo` parameter).
   */
  private async callToolAtGroupRepo(
    method: string,
    params: Record<string, unknown>,
  ): Promise<unknown> {
    await this.refreshRepos();

    if (
      params.service !== undefined &&
      params.service !== null &&

View on GitHub (pinned to 0d1aed942f)

Solutions

  1. Replace group_query with impact/query/context using repo "@<groupName>" (append "/<memberPath>" to scope to one member).
  2. Use the MCP resources gitnexus://group/{name}/contracts and gitnexus://group/{name}/status instead of group_contracts/group_status.
  3. Keep group_list and group_sync — they still exist and are the only valid group tools.
  4. Search your client configs/agent instructions for 'group_query', 'group_contracts', 'group_status' and migrate every occurrence.

Example fix

# before: removed group tools
{"tool": "group_query", "args": {"group": "mygroup", "search_query": "retry"}}
{"tool": "group_status", "args": {"group": "mygroup"}}

# after: repo "@group" parameter + MCP resources
{"tool": "query", "args": {"search_query": "retry", "repo": "@mygroup"}}
{"tool": "impact", "args": {"target": "login", "repo": "@mygroup/packages/api"}}
# status/contracts: read resource gitnexus://group/mygroup/status
Defensive patterns

Strategy: validation

Validate before calling

// Migrate group calls to the post-1.5.0 surface before dispatch
const REMOVED_GROUP_TOOLS = new Set(['group_query', 'group_contracts', 'group_status']);
const VALID_GROUP_TOOLS = new Set(['group_list', 'group_sync']);

function normalizeGroupCall(method: string, params: Record<string, unknown>) {
  if (REMOVED_GROUP_TOOLS.has(method)) {
    const group = params.group ?? params.name;
    if (method === 'group_query') return { method: 'query', args: { ...params, repo: `@${group}` } };
    return { method: 'resource', args: { uri: `gitnexus://group/${group}/${method === 'group_status' ? 'status' : 'contracts'}` } };
  }
  if (method.startsWith('group_') && !VALID_GROUP_TOOLS.has(method)) {
    throw new Error(`Unknown group tool "${method}" — valid: ${[...VALID_GROUP_TOOLS].join(', ')}`);
  }
  return { method, args: params };
}

Type guard

const isGroupToolCall = (m: string): m is 'group_list' | 'group_sync' =>
  m === 'group_list' || m === 'group_sync';

Try / catch

try {
  return await backend.callTool(method, params);
} catch (err) {
  if (err instanceof Error && err.message.startsWith('Unknown group tool:')) {
    // migrate the call instead of surfacing it: group_query → repo "@group", status → resource
    const migrated = normalizeGroupCall(method, params);
    return migrated.method === 'resource'
      ? client.readResource(migrated.args.uri)
      : backend.callTool(migrated.method, migrated.args);
  }
  throw err;
}

Prevention

When it happens

Trigger: An MCP client or agent prompt calling the removed tools group_query/group_contracts/group_status, or any misspelled group_* method — the group dispatch switch has exactly two valid cases.

Common situations: Configs and tutorials written against pre-1.5.0 GitNexus; AI agents replaying tool names learned from older docs; clients that never migrated to the repo "@group" parameter form after the cross-repo #794 rework.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@0d1aed942f (2026-08-20). Data as JSON: /api/errors/c6208539364d7634. Report an issue: GitHub.