abhigyanpatwari/GitNexus · error

Group routing is unavailable when an MCP repository allowlis

Error message

Group routing is unavailable when an MCP repository allowlist is set.

What it means

Thrown by McpRepositoryPolicy.repoForArgs when an allowlist is configured (GITNEXUS_MCP_ALLOWED_REPOS set, so restricted=true) and a tool call passes a repo argument starting with '@'. Group routing and repository allowlists are mutually exclusive by design: an allowlist pins the server to specific local repos, so it must not fan a call out across a group.

Source

Thrown at gitnexus/src/mcp/repository-policy.ts:141

        .filter((name) => registryNameCounts.get(name) === 1),
    );
  }

  private resolveRuntimeRepo(specifier: string): ResolvedRepository {
    const result = resolveSpecifier(specifier, this.registry);
    if (!result.repo || (this.restricted && !this.allowedPathKeys.has(result.repo.pathKey))) {
      throw unavailableRepositoryError();
    }
    return result.repo;
  }

  private repoForArgs(args: Record<string, unknown> | undefined): ResolvedRepository | undefined {
    const explicit = args?.repo;
    if (explicit !== undefined) {
      if (typeof explicit !== 'string') throw unavailableRepositoryError();
      if (explicit.trim().startsWith('@')) {
        if (this.restricted) {
          throw new Error('Group routing is unavailable when an MCP repository allowlist is set.');
        }
        return undefined;
      }
      return this.resolveRuntimeRepo(explicit);
    }

    if (this.defaultRepo) return this.defaultRepo;
    if (this.restricted && this.allowed.length === 1) return this.allowed[0];
    if (this.restricted && this.allowed.length > 1) {
      throw new Error('Specify an explicit repo because multiple repositories are allowed.');
    }
    return undefined;
  }

  private normalizeToolArgs(
    args: Record<string, unknown> | undefined,
  ): Record<string, unknown> | undefined {
    if (!this.configured) return args;

View on GitHub (pinned to 52924ef12c)

Solutions

  1. Pass an explicit repo that is on the allowlist, e.g. repo: 'frontend' — the policy resolves it against the allowed entries.
  2. If group routing is required, remove GITNEXUS_MCP_ALLOWED_REPOS from the server environment.
  3. Update shared agent templates to derive the repo argument from the deployment configuration instead of hard-coding '@group'.

Example fix

# server env (before)
GITNEXUS_MCP_ALLOWED_REPOS=frontend,backend
# client call (before): repo: '@org'

# client call (after)
await client.callTool({ name: 'query', arguments: { search_query: 'auth', repo: 'frontend' } });
Defensive patterns

Strategy: validation

Validate before calling

function assertRepoCompatibleWithAllowlist(repo: unknown, allowlistConfigured: boolean) {
  if (allowlistConfigured && typeof repo === 'string' && repo.trim().startsWith('@')) {
    throw new Error('This endpoint has a repository allowlist; pass an explicit repo instead of @group.');
  }
}

Type guard

const isAllowedRepoArg = (repo: unknown): repo is string =>
  typeof repo === 'string' && !repo.trim().startsWith('@');

Try / catch

try {
  await client.callTool({ name: 'query', arguments: { search_query: q, repo } });
} catch (e) {
  if (e instanceof Error && e.message.includes('Group routing is unavailable')) {
    throw new Error('Group routing disabled by allowlist — ask the operator for the repo list.');
  }
  throw e;
}

Prevention

When it happens

Trigger: With GITNEXUS_MCP_ALLOWED_REPOS set, calling any MCP tool with arguments like { repo: '@org' } (leading whitespace trimmed). Note the same call succeeds when no allowlist is configured.

Common situations: A server originally deployed for cross-repo group queries later gets an allowlist tightened onto it, and existing client prompts keep sending @group repos. Agents copy the group-routing example from cross-repo docs into an allowlisted deployment.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@52924ef12c (2026-08-20). Data as JSON: /api/errors/19b6671383d8aa1d. Report an issue: GitHub.