musistudio/claude-code-router · error · Error

${label} is invalid.

Error message

${label} is invalid.

What it means

validateRemoteHostname normalizes the hostname and throws '${label} is invalid.' when nothing remains after trimming, lowercasing, and stripping a trailing dot — i.e. the URL had no usable host.

Source

Thrown at packages/core/src/providers/manifest-service.ts:225

  }
}

async function validatePublicHttpsUrl(value: string, label: string): Promise<void> {
  const url = new URL(providerUrlWithDefaultScheme(value));
  if (url.protocol !== "https:") {
    throw new Error(`${label} from a remote manifest must use https.`);
  }
  if (url.username || url.password) {
    throw new Error(`${label} cannot include credentials.`);
  }
  validateRemoteHostname(url.hostname, label);
  await resolveSafeAddress(url.hostname);
}

function validateRemoteHostname(hostname: string, label: string): void {
  const normalized = hostname.trim().toLowerCase().replace(/\.$/, "");
  if (!normalized) {
    throw new Error(`${label} is invalid.`);
  }
  if (
    normalized === "localhost" ||
    normalized.endsWith(".localhost") ||
    normalized.endsWith(".home") ||
    normalized.endsWith(".lan") ||
    normalized.endsWith(".local") ||
    normalized.endsWith(".internal")
  ) {
    throw new Error(`${label} cannot target a local or internal host.`);
  }
}

async function resolveSafeAddress(hostname: string): Promise<SafeAddress> {
  const addresses = await lookup(hostname, { all: true, verbatim: true });
  if (addresses.length === 0) {
    throw new Error(`Could not resolve host: ${hostname}`);
  }

View on GitHub (pinned to 99f24806c6)

Solutions

  1. Fix or fill in the host portion of the URL in the manifest/provider config
  2. Add a pre-flight check that new URL(...).hostname is non-empty before shipping config
  3. If the value comes from env substitution, fail fast at startup when the variable is empty

Example fix

// before
"baseUrl": `https://${process.env.PROVIDER_HOST}` // HOST unset
// after
const host = process.env.PROVIDER_HOST;
if (!host) throw new Error('PROVIDER_HOST is required');
"baseUrl": `https://${host}`
Defensive patterns

Strategy: validation

Validate before calling

const host = new URL(providerUrlWithDefaultScheme(url)).hostname.trim().toLowerCase().replace(/\.$/,'');
if (!host) throw new Error('hostname is empty');

Type guard

function hasHostname(v: string): boolean { try { return new URL(v).hostname.length > 0; } catch { return false; } }

Prevention

When it happens

Trigger: A URL whose hostname normalizes to empty, e.g. 'https://', 'https://.', or a value like 'https://:8443' that parses but yields no host.

Common situations: Template placeholder left unfilled (https://${HOST} with HOST empty), malformed URL construction, or trailing-dot-only hostnames in hand-written manifests.

Related errors


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