musistudio/claude-code-router · error · Error
Unsupported provider protocol: ${value}
Error message
Unsupported provider protocol: ${value} What it means
normalizeProviderProtocol validates an optional protocol field on provider deep links/manifests against the known GatewayProviderProtocol set (providerProtocols). An unrecognized protocol string (e.g. 'openai-completions' when only specific values are supported) throws with the offending value embedded.
Source
Thrown at packages/core/src/contracts/deep-link.ts:497
const url = new URL(value);
if (url.protocol !== "https:") {
throw new Error("Provider manifest URL must use https.");
}
if (url.username || url.password) {
throw new Error("Provider manifest URL cannot include credentials.");
}
if (!url.hostname) {
throw new Error("Provider manifest URL is invalid.");
}
}
function normalizeProviderProtocol(value: string | undefined): GatewayProviderProtocol | undefined {
if (!value) {
return undefined;
}
const protocol = value.trim();
if (!providerProtocols.has(protocol as GatewayProviderProtocol)) {
throw new Error(`Unsupported provider protocol: ${value}`);
}
return protocol as GatewayProviderProtocol;
}
function readDeepLinkModels(params: URLSearchParams, payload: Record<string, unknown> | undefined): string[] {
const values = [
...params.getAll("models"),
...payloadModels(payload)
];
const seen = new Set<string>();
const models: string[] = [];
for (const value of values) {
for (const model of splitModelValue(value)) {
if (model.length > maxModelLength) {
throw new Error("Model name is too long.");
}
if (seen.has(model)) {View on GitHub (pinned to 99f24806c6)
Solutions
- Use only the protocol identifiers exported/supported by the current version (check the GatewayProviderProtocol type / providerProtocols set)
- Omit protocol to use the default rather than guessing a value
- Upgrade the library if a newly added provider protocol should be supported
Example fix
// before
{"provider":{"protocol":"openai-chat-completions","base_url":"..."}}
// after
{"provider":{"protocol":"openai","base_url":"..."}} Defensive patterns
Strategy: type-guard
Validate before calling
const known = new Set(["openai", "anthropic", ...]); if (protocol && !known.has(protocol)) return useDefault();
Type guard
const isSupportedProtocol = (v: string | undefined, known: ReadonlySet<string>): v is string => !v || known.has(v.trim());
Try / catch
try { parseProviderDeepLinkPayload(url); } catch (e) { if (e instanceof Error && e.message.startsWith("Unsupported provider protocol")) return fallbackToDefaultProtocol(); throw e; } Prevention
- Reference the exported GatewayProviderProtocol values, not string literals
- Omit protocol rather than guessing; keep library updated for new protocol ids
When it happens
Trigger: Passing protocol="anthropic-beta" or any string not in providerProtocols in a ccr:// link or provider manifest.
Common situations: Providers adding new protocol identifiers before this library supports them; typos/casing differences ('OpenAI' vs 'openai'); manifests written against a different gateway's schema.
Related errors
- Unsupported link protocol.
- ${label} is too long.
- Provider link is too long.
- Unsupported CCR link target.
- Provider manifest must be a JSON object.
AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27).
Data as JSON: /api/errors/e059a4df597ba1fe.
Report an issue: GitHub.