musistudio/claude-code-router · error · Error

Unsupported CCR link target.

Error message

Unsupported CCR link target.

What it means

parseProviderManifestDeepLinkPayload requires the link's host (or first path segment, when the host form like ccr:///provider is used) to equal providerDeepLinkHost. This error means the link targets a different deep-link route, so it cannot be interpreted as a provider manifest link.

Source

Thrown at packages/core/src/contracts/deep-link.ts:84

    };
  }
}

export function parseProviderManifestDeepLinkPayload(rawUrl: string): ProviderManifestDeepLinkPayload | undefined {
  const value = rawUrl.trim();
  if (value.length > maxDeepLinkLength) {
    throw new Error("Provider link is too long.");
  }

  const url = new URL(value);
  if (url.protocol !== `${appDeepLinkProtocol}:`) {
    throw new Error("Unsupported link protocol.");
  }

  const host = url.hostname.toLowerCase();
  const firstPathSegment = url.pathname.split("/").filter(Boolean)[0]?.toLowerCase();
  if (host !== providerDeepLinkHost && firstPathSegment !== providerDeepLinkHost) {
    throw new Error("Unsupported CCR link target.");
  }

  const payload = readPayloadRecord(url.searchParams);
  const manifestUrl = boundedString(
    firstStringParam(url.searchParams, ["manifest"]) ??
      firstPayloadString(payload, ["manifest"]),
    maxManifestUrlLength,
    "Manifest URL"
  );
  if (!manifestUrl) {
    return undefined;
  }
  validateManifestUrl(manifestUrl);
  return {
    url: manifestUrl
  };
}

View on GitHub (pinned to 99f24806c6)

Solutions

  1. Route the link to the parser matching its host (dispatch on url.hostname first)
  2. Regenerate/fix the link so the host is the provider deep-link host
  3. If the host constant changed across versions, update link generators to the current host

Example fix

// before
parseProviderManifestDeepLinkPayload("ccr://agents/open?manifest=...");
// after
parseProviderManifestDeepLinkPayload("ccr://provider/install?manifest=...");
Defensive patterns

Strategy: validation

Validate before calling

const u = new URL(rawUrl.trim()); const host = u.hostname.toLowerCase(); if (host !== "provider" && u.pathname.split("/").filter(Boolean)[0] !== "provider") return routeElsewhere(u);

Type guard

const isProviderManifestLink = (u: string) => {
  const p = new URL(u.trim());
  const first = p.pathname.split("/").filter(Boolean)[0]?.toLowerCase();
  return p.protocol === "ccr:" && (p.hostname.toLowerCase() === "provider" || first === "provider");
};

Try / catch

try { parseProviderManifestDeepLinkPayload(url); } catch (e) { if (e instanceof Error && e.message === "Unsupported CCR link target.") return dispatchToOtherHandler(url); throw e; }

Prevention

When it happens

Trigger: Calling parseProviderManifestDeepLinkPayload with a ccr:// link whose hostname and first path segment are not the provider host constant (e.g. ccr://settings/open or ccr://agent/...).

Common situations: Routing a generic app deep link into the provider-manifest parser; host renamed in a newer schema (e.g. 'provider' vs 'providers'); dispatcher missing a host check before calling this parser.

Related errors


AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27). Data as JSON: /api/errors/73474cc29922da35. Report an issue: GitHub.