abhigyanpatwari/GitNexus · error

Unknown resource URI: ${uri}

Error message

Unknown resource URI: ${uri}

What it means

Thrown by parseResourceUri when the resource URI cannot be parsed by the URL constructor at all. This is the first gate of GitNexus MCP resource parsing: only the two exact flat URIs (gitnexus://repos, gitnexus://setup) bypass parsing; everything else must at least be a well-formed URL or the URI is declared unknown with the original string echoed back.

Source

Thrown at gitnexus/src/mcp/resources.ts:170

  const v = raw.trim().toLowerCase();
  if (v === 'true' || v === '1') return true;
  if (v === 'false' || v === '0') return false;
  return undefined;
}

/**
 * Parse a GitNexus resource URI (repos, setup, per-repo, or per-group templates).
 * Used by `readResource` and tests (round-trip / dispatch coverage).
 */
export function parseResourceUri(uri: string): ParsedGitnexusResource {
  if (uri === 'gitnexus://repos') return { kind: 'repos' };
  if (uri === 'gitnexus://setup') return { kind: 'setup' };

  let u: URL;
  try {
    u = new URL(uri);
  } catch {
    throw new Error(`Unknown resource URI: ${uri}`);
  }

  if (u.protocol !== 'gitnexus:') {
    throw new Error(`Unknown resource URI: ${uri}`);
  }

  if (u.hostname === 'group') {
    const segments = u.pathname
      .replace(/^\/+|\/+$/g, '')
      .split('/')
      .filter(Boolean);
    if (segments.length < 2) {
      throw new Error(
        `Invalid group resource URI (expected gitnexus://group/{name}/contracts or .../status): ${uri}`,
      );
    }
    const tail = segments[segments.length - 1]!;
    if (tail !== 'contracts' && tail !== 'status') {

View on GitHub (pinned to 0d1aed942f)

Solutions

  1. Send fully-formed URIs of the form gitnexus://repo/{name}/{resource} or gitnexus://group/{name}/contracts|status.
  2. Percent-encode dynamic path segments (encodeURIComponent) before composing the URI.
  3. If you only have a repo name, resolve it first via the gitnexus://repos listing, then build the URI.

Example fix

// before
const uri = `gitnexus://repo/${repoName}/context`; // repoName = 'my repo'

// after
const uri = `gitnexus://repo/${encodeURIComponent(repoName)}/context`;
Defensive patterns

Strategy: validation

Validate before calling

function isParsableResourceUri(uri: string): boolean {
  if (uri === 'gitnexus://repos' || uri === 'gitnexus://setup') return true;
  try { new URL(uri); return true; } catch { return false; }
}
if (!isParsableResourceUri(uri)) throw new Error(`Not a valid resource URI: ${uri}`);

Type guard

const isWellFormedUri = (uri: unknown): uri is string =>
  typeof uri === 'string' && (() => { try { new URL(uri); return true; } catch { return false; } })();

Try / catch

try {
  return await client.readResource({ uri });
} catch (e) {
  if (e instanceof Error && /Unknown resource URI/.test(e.message)) {
    return null; // drop malformed entries when replaying a saved list
  }
  throw e;
}

Prevention

When it happens

Trigger: Reading a resource with a string that is not a valid URL — e.g. 'frontend/context', 'gitnexus:/repo/frontend' is parseable but other typos aside, strings with spaces or control characters like 'gitnexus:// repo/x' or 'not a uri' fail new URL() and hit this branch.

Common situations: Clients build URIs by string concatenation with unescaped names (spaces in repo names), pass a repo name instead of a full URI, or template systems inject empty/malformed segments. Copying a URI from logs where it was already mangled.

Related errors


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