abhigyanpatwari/GitNexus · error

Group resources are not available in GitNexus MCP read-only

Error message

Group resources are not available in GitNexus MCP read-only mode.

What it means

Thrown by assertMcpReadOnlyResource when reading an MCP resource whose URI targets the group host while read-only mode is active. Any URI that parses to protocol gitnexus: with hostname 'group' (compared case-insensitively, since the non-special gitnexus: scheme keeps opaque hosts) is a group resource; if the URI does not even parse, a fallback regex fails it closed when it still looks group-shaped.

Source

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

  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';
  } catch {
    // Invalid resource URIs are rejected by the normal parser. This fallback
    // keeps obviously group-shaped malformed inputs fail-closed as well.
    isGroupResource = /^gitnexus:\/\/group(?:\/|$)/iu.test(uri);
  }

  if (isGroupResource) {
    throw new Error('Group resources are not available in GitNexus MCP read-only mode.');
  }
}

// Cosmetic only: dispatch enforcement above is the actual boundary. If the
// generated resource format drifts and a hidden route slips through here, the
// caller still gets a clean rejection at dispatch.
export function filterMcpReadOnlyResourceContent(content: string, readOnly: boolean): string {
  if (!readOnly) return content;
  return content
    .split('\n')
    .filter(
      (line) =>
        !/^\s*-\s+(?:rename|cypher|group_sync|group_list):/u.test(line) &&
        !/^\|\s*`(?:rename|cypher|group_sync|group_list)`\s*\|/u.test(line) &&
        !line.includes('gitnexus://group/'),
    )
    .join('\n');
}

View on GitHub (pinned to aac7515d2a)

Solutions

  1. Read repo-scoped resources instead: gitnexus://repo/{name}/context, .../clusters, .../processes.
  2. Read the flat lists gitnexus://repos and gitnexus://setup, which remain available in read-only mode.
  3. If group resources are required, disable read-only mode on the server.

Example fix

# before (read-only server)
read_resource 'gitnexus://group/my-group/contracts'

# after
read_resource 'gitnexus://repo/frontend/contracts'
Defensive patterns

Strategy: validation

Validate before calling

function isGroupResourceUri(uri: string): boolean {
  try {
    const u = new URL(uri);
    return u.protocol.toLowerCase() === 'gitnexus:' && u.hostname.toLowerCase() === 'group';
  } catch {
    return /^gitnexus:\/\/group(?:\/|$)/iu.test(uri);
  }
}
if (readOnly && isGroupResourceUri(uri)) {
  throw new Error('Group resources disabled in read-only mode; use gitnexus://repo/{name}/...');
}

Type guard

const isReadableInReadOnlyMode = (uri: string): boolean => !isGroupResourceUri(uri);

Try / catch

try {
  return await client.readResource({ uri });
} catch (e) {
  if (e instanceof Error && e.message.includes('not available in GitNexus MCP read-only mode')) {
    return null; // skip group resources when iterating a saved bookmark list
  }
  throw e;
}

Prevention

When it happens

Trigger: With GITNEXUS_MCP_READ_ONLY=1, reading a resource like gitnexus://group/my-group/contracts, gitnexus://GROUP/my-group/status, or a malformed group-shaped URI such as 'gitnexus://group' via the MCP read_resource / resources/read call.

Common situations: A dashboard or agent enumerates resources with a client configured for group mode, then reuses the same URIs against a read-only endpoint. Case-variation ('GITNEXUS://Group/…') is attempted to dodge the filter and still fails, as intended.

Related errors


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