{"record":{"id":"73474cc29922da35","repo":"musistudio/claude-code-router","slug":"unsupported-ccr-link-target","errorCode":null,"errorMessage":"Unsupported CCR link target.","messagePattern":"Unsupported CCR link target\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/contracts/deep-link.ts","lineNumber":84,"sourceCode":"    };\n  }\n}\n\nexport function parseProviderManifestDeepLinkPayload(rawUrl: string): ProviderManifestDeepLinkPayload | undefined {\n  const value = rawUrl.trim();\n  if (value.length > maxDeepLinkLength) {\n    throw new Error(\"Provider link is too long.\");\n  }\n\n  const url = new URL(value);\n  if (url.protocol !== `${appDeepLinkProtocol}:`) {\n    throw new Error(\"Unsupported link protocol.\");\n  }\n\n  const host = url.hostname.toLowerCase();\n  const firstPathSegment = url.pathname.split(\"/\").filter(Boolean)[0]?.toLowerCase();\n  if (host !== providerDeepLinkHost && firstPathSegment !== providerDeepLinkHost) {\n    throw new Error(\"Unsupported CCR link target.\");\n  }\n\n  const payload = readPayloadRecord(url.searchParams);\n  const manifestUrl = boundedString(\n    firstStringParam(url.searchParams, [\"manifest\"]) ??\n      firstPayloadString(payload, [\"manifest\"]),\n    maxManifestUrlLength,\n    \"Manifest URL\"\n  );\n  if (!manifestUrl) {\n    return undefined;\n  }\n  validateManifestUrl(manifestUrl);\n  return {\n    url: manifestUrl\n  };\n}\n","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/musistudio/claude-code-router/blob/99f24806c6a2c660b16e53e95211c517448a6c90/packages/core/src/contracts/deep-link.ts#L66-L102","documentation":"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.","triggerScenarios":"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/...).","commonSituations":"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.","solutions":["Route the link to the parser matching its host (dispatch on url.hostname first)","Regenerate/fix the link so the host is the provider deep-link host","If the host constant changed across versions, update link generators to the current host"],"exampleFix":"// before\nparseProviderManifestDeepLinkPayload(\"ccr://agents/open?manifest=...\");\n// after\nparseProviderManifestDeepLinkPayload(\"ccr://provider/install?manifest=...\");","handlingStrategy":"validation","validationCode":"const u = new URL(rawUrl.trim()); const host = u.hostname.toLowerCase(); if (host !== \"provider\" && u.pathname.split(\"/\").filter(Boolean)[0] !== \"provider\") return routeElsewhere(u);","typeGuard":"const isProviderManifestLink = (u: string) => {\n  const p = new URL(u.trim());\n  const first = p.pathname.split(\"/\").filter(Boolean)[0]?.toLowerCase();\n  return p.protocol === \"ccr:\" && (p.hostname.toLowerCase() === \"provider\" || first === \"provider\");\n};","tryCatchPattern":"try { parseProviderManifestDeepLinkPayload(url); } catch (e) { if (e instanceof Error && e.message === \"Unsupported CCR link target.\") return dispatchToOtherHandler(url); throw e; }","preventionTips":["Dispatch deep links on host before parser selection","Keep one source of truth for the provider host constant"],"tags":["deep-link","routing","validation"],"backgroundTag":"deep-link-wrong-target","analyzedSha":"99f24806c6a2c660b16e53e95211c517448a6c90","analyzedAt":"2026-08-27T04:11:01.184Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}