abhigyanpatwari/GitNexus · error

Group resources are unavailable when an MCP repository allow

Error message

Group resources are unavailable when an MCP repository allowlist is set.

What it means

Thrown by McpRepositoryPolicy.assertResourceUri in allowlist (restricted) mode when a resource URI fails URL parsing but still matches the group-shaped pattern ^gitnexus:\/\/group(\/|$). It is a fail-closed guard: malformed input that looks like a group resource is rejected here rather than being passed along on the assumption that the downstream parser would reject it anyway.

Source

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

      return backend.selectToolRepository(repo ?? this.defaultRepo?.path, branch, options);
    }
    const selected = this.repoForArgs(repo === undefined ? undefined : { repo });
    // Restricted policies never allow cwd to select outside the configured
    // set; once policy supplies an explicit path, the public resolver is enough.
    return backend.resolveRepo(selected?.path, branch);
  }

  assertResourceUri(uri: string): void {
    if (!this.restricted) return;
    let parsed: URL;
    try {
      parsed = new URL(uri);
    } catch {
      // resources.ts parses with the same URL call, so anything that fails
      // here fails there too today. Keep obviously group- or repo-shaped
      // malformed inputs fail-closed anyway in case the parsers ever drift.
      if (/^gitnexus:\/\/group(?:\/|$)/iu.test(uri)) {
        throw new Error('Group resources are unavailable when an MCP repository allowlist is set.');
      }
      const repoShaped = /^gitnexus:\/\/repo\/([^/]+)/iu.exec(uri);
      if (repoShaped) this.resolveRuntimeRepo(decodeURIComponent(repoShaped[1]));
      return;
    }
    // gitnexus: is a non-special URL scheme, so the host is opaque and NOT
    // lowercased by the parser — compare case-insensitively like
    // read-only-policy.ts does.
    if (parsed.protocol.toLowerCase() !== 'gitnexus:') return;
    const hostname = parsed.hostname.toLowerCase();
    if (hostname === 'group') {
      throw new Error('Group resources are unavailable when an MCP repository allowlist is set.');
    }
    if (hostname !== 'repo') return;
    const repoName = parsed.pathname.split('/').filter(Boolean)[0];
    if (!repoName) return;
    this.resolveRuntimeRepo(decodeURIComponent(repoName));
  }

View on GitHub (pinned to 52924ef12c)

Solutions

  1. Fix the URI to a well-formed group form — but note well-formed group URIs are also rejected in restricted mode, so switch to repo-scoped URIs: gitnexus://repo/{name}/context.
  2. Check how the URI string is produced (escaping, encoding) if it unexpectedly fails URL parsing.
  3. Remove GITNEXUS_MCP_ALLOWED_REPOS if group resources are genuinely needed.

Example fix

# before (allowlist set, malformed URI)
read_resource 'gitnexus:\/\/group\/org\/contracts'

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

Strategy: validation

Validate before calling

function isGroupShaped(uri: string): boolean {
  try {
    new URL(uri);
    return false; // parseable — handled by the well-formed branch
  } catch {
    return /^gitnexus:\/\/group(?:\/|$)/iu.test(uri);
  }
}
if (restricted && isGroupShaped(uri)) {
  throw new Error('Malformed group-shaped URI under allowlist — use gitnexus://repo/{name}/...');
}

Type guard

const isWellFormedUri = (uri: string): boolean => {
  try { new URL(uri); return true; } catch { return false; } };

Try / catch

try {
  await client.readResource({ uri });
} catch (e) {
  if (e instanceof Error && e.message.includes('Group resources are unavailable')) {
    return null; // skip group-shaped entries when iterating under an allowlist
  }
  throw e;
}

Prevention

When it happens

Trigger: GITNEXUS_MCP_ALLOWED_REPOS set, then reading a resource whose URI is unparseable by new URL() yet group-shaped — e.g. 'gitnexus:\/\/group\/name\/contracts' with literal backslashes, or other malformed variants that still begin gitnexus://group.

Common situations: URI templating bugs (bad escaping in shell scripts or JSON), hand-built URI strings with wrong slashes, or porting resource URIs through a system that mangles 'gitnexus://group/...' into a non-parsing variant while the allowlist lockdown is active.

Related errors


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