{"record":{"id":"c51d54c13568657c","repo":"musistudio/claude-code-router","slug":"label-from-a-remote-manifest-must-use-https","errorCode":null,"errorMessage":"${label} from a remote manifest must use https.","messagePattern":"(.+?) from a remote manifest must use https\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/providers/manifest-service.ts","lineNumber":213,"sourceCode":"  }\n}\n\nfunction validateProviderApiKeyTarget(provider: ProviderDeepLinkPayload, endpoint: string): void {\n  const issue = providerEndpointCanReceiveProviderApiKey({\n    apiKey: \"manifest-provider-api-key\",\n    endpoint,\n    providerName: provider.name,\n    providerPresetId: findProviderPresetByBaseUrl(provider.baseUrl)?.id\n  });\n  if (issue) {\n    throw new Error(issue.message);\n  }\n}\n\nasync function validatePublicHttpsUrl(value: string, label: string): Promise<void> {\n  const url = new URL(providerUrlWithDefaultScheme(value));\n  if (url.protocol !== \"https:\") {\n    throw new Error(`${label} from a remote manifest must use https.`);\n  }\n  if (url.username || url.password) {\n    throw new Error(`${label} cannot include credentials.`);\n  }\n  validateRemoteHostname(url.hostname, label);\n  await resolveSafeAddress(url.hostname);\n}\n\nfunction validateRemoteHostname(hostname: string, label: string): void {\n  const normalized = hostname.trim().toLowerCase().replace(/\\.$/, \"\");\n  if (!normalized) {\n    throw new Error(`${label} is invalid.`);\n  }\n  if (\n    normalized === \"localhost\" ||\n    normalized.endsWith(\".localhost\") ||\n    normalized.endsWith(\".home\") ||\n    normalized.endsWith(\".lan\") ||","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/musistudio/claude-code-router/blob/99f24806c6a2c660b16e53e95211c517448a6c90/packages/core/src/providers/manifest-service.ts#L195-L231","documentation":"validatePublicHttpsUrl rejects any URL from a remote manifest that is not https. Remote manifests are fetched over the network and their derived URLs will carry credentials/tokens, so plaintext http would allow interception.","triggerScenarios":"validatePublicHttpsUrl(value, label) where the parsed URL protocol is 'http:' (or any non-https scheme) — e.g. provider.baseUrl 'http://api.example.com' or a connector endpoint without a scheme defaulting to http.","commonSituations":"Manifest authored with http:// for local testing then deployed remotely; scheme omitted so providerUrlWithDefaultScheme applied http; or an internal tool URL pasted into a public manifest.","solutions":["Change the URL in the manifest to https://...","Obtain a TLS certificate for the host (e.g. Let's Encrypt) if the service is public","For local testing, use a local manifest instead of a remote one (the remote https rule does not apply)"],"exampleFix":"// before\n\"baseUrl\": \"http://api.example.com\"\n// after\n\"baseUrl\": \"https://api.example.com\"","handlingStrategy":"validation","validationCode":"if (!provider.baseUrl.startsWith('https://')) throw new Error('remote manifest URLs must use https');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Default new manifest URLs to https://","CI-lint remote manifests for http:// endpoints"],"tags":["manifest","https","ssrf","url-validation"],"backgroundTag":"insecure-url-rejected","analyzedSha":"99f24806c6a2c660b16e53e95211c517448a6c90","analyzedAt":"2026-08-27T04:11:01.184Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}