abhigyanpatwari/GitNexus · error

Parameter "${groupOnlyArg}" is not available in GitNexus MCP

Error message

Parameter "${groupOnlyArg}" is not available in GitNexus MCP read-only mode.

What it means

Thrown by assertMcpReadOnlyToolCall in read-only mode when a tool call includes crossDepth or subgroup — parameters that only have meaning on the (disabled) @group routing path. The code comments explain they are rejected anyway so the advertised schema and the dispatch contract stay in agreement: read-only mode must not appear to accept group-only knobs.

Source

Thrown at gitnexus/src/mcp/read-only-policy.ts:47

export function assertMcpReadOnlyToolCall(
  toolName: string,
  args: Record<string, unknown> | undefined,
  readOnly: boolean,
): void {
  if (!readOnly) return;
  if (!MCP_READ_ONLY_TOOLS.has(toolName) && !MCP_READ_ONLY_ALIASES.has(toolName)) {
    throw new Error(`Tool "${toolName}" is not available in GitNexus MCP read-only mode.`);
  }
  if (typeof args?.repo === 'string' && args.repo.trim().startsWith('@')) {
    throw new Error('Group routing is not available in GitNexus MCP read-only mode.');
  }
  // crossDepth/subgroup only do anything on the @group path rejected above,
  // but rejecting them here keeps the advertised schema and the dispatch
  // contract in agreement.
  for (const groupOnlyArg of ['crossDepth', 'subgroup']) {
    if (args?.[groupOnlyArg] !== undefined) {
      throw new Error(
        `Parameter "${groupOnlyArg}" is not available in GitNexus MCP read-only mode.`,
      );
    }
  }
}

export function readOnlyResourceTemplateAllowed(uriTemplate: string, readOnly: boolean): boolean {
  return !readOnly || !/^gitnexus:\/\/group\//iu.test(uriTemplate);
}

export function assertMcpReadOnlyResource(uri: string, readOnly: boolean): void {
  if (!readOnly) return;

  let isGroupResource = false;
  try {
    const parsed = new URL(uri);
    isGroupResource =
      parsed.protocol.toLowerCase() === 'gitnexus:' && parsed.hostname.toLowerCase() === 'group';

View on GitHub (pinned to aac7515d2a)

Solutions

  1. Remove crossDepth and subgroup from the arguments object entirely before sending in read-only mode.
  2. Strip null values too — the guard tests !== undefined, so subgroup: null also throws; omit the key or set it to undefined.
  3. If group parameters are needed, run against a server without read-only mode enabled.

Example fix

// before
const args = { search_query: 'auth', repo: 'frontend', subgroup: 'services', crossDepth: 2 };
await client.callTool({ name: 'query', arguments: args });

// after
const args = { search_query: 'auth', repo: 'frontend' };
await client.callTool({ name: 'query', arguments: args });
Defensive patterns

Strategy: validation

Validate before calling

const GROUP_ONLY_ARGS = ['crossDepth', 'subgroup'];
function stripGroupOnlyArgs(args: Record<string, unknown>, readOnly: boolean) {
  if (!readOnly) return args;
  const clean = { ...args };
  for (const k of GROUP_ONLY_ARGS) {
    if (clean[k] !== undefined) delete clean[k]; // null triggers too: !== undefined check
  }
  return clean;
}

Type guard

const hasNoGroupOnlyArgs = (args: Record<string, unknown>): boolean =>
  args.crossDepth === undefined && args.subgroup === undefined;

Try / catch

try {
  await client.callTool({ name: 'query', arguments });
} catch (e) {
  if (e instanceof Error && /Parameter "(crossDepth|subgroup)" is not available/.test(e.message)) {
    const { crossDepth, subgroup, ...rest } = arguments;
    return client.callTool({ name: 'query', arguments: rest }); // one retry with cleaned args
  }
  throw e;
}

Prevention

When it happens

Trigger: With GITNEXUS_MCP_READ_ONLY=1, calling a tool with arguments containing crossDepth or subgroup, even with a normal non-group repo — e.g. { repo: 'frontend', subgroup: 'services', crossDepth: 2 }.

Common situations: A client built for cross-repo group queries sends both parameters unconditionally. An agent template with default arguments (subgroup: undefined is fine, but explicit null or a value triggers it — the check is args[key] !== undefined, so pass undefined or omit, never null).

Related errors


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