{"record":{"id":"dea9c09d08afe2c1","repo":"musistudio/claude-code-router","slug":"issue-message-dea9c0","errorCode":null,"errorMessage":"${issue.message}","messagePattern":"\\$\\{issue\\.message\\}","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/providers/manifest-service.ts","lineNumber":206,"sourceCode":"    ].filter((endpoint): endpoint is string => Boolean(endpoint?.trim()));\n    for (const endpoint of endpoints) {\n      if (/^https?:\\/\\//i.test(endpoint)) {\n        await validatePublicHttpsUrl(endpoint, \"Fetch usage URL\");\n        validateProviderApiKeyTarget(provider, endpoint);\n      }\n    }\n  }\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) {","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/musistudio/claude-code-router/blob/99f24806c6a2c660b16e53e95211c517448a6c90/packages/core/src/providers/manifest-service.ts#L188-L224","documentation":"A connector inside a remote provider manifest failed the apiKey-target safety check: validateProviderApiKeyTarget receives a synthetic api key, the connector endpoint, the provider name and preset id, and rejects endpoints that are unsafe targets for stored credentials (e.g. credential-host mismatch). It prevents a remote manifest from exfiltrating API keys to an unrelated host.","triggerScenarios":"validateRemoteAccountConnector() on a connector whose endpoint does not match the provider's baseUrl/preset (findProviderPresetByBaseUrl returns a different preset, or endpoint host differs), so providerApiKeySafetyIssue/validateProviderApiKeyTarget reports an issue.","commonSituations":"Manifest connector endpoints pointing at a different domain than the provider base URL, connectors added for telemetry that still request the user's API key, or typos in connector endpoint URLs.","solutions":["Make the connector endpoint use the same host (or an approved host) as the provider's baseUrl","Remove the connector from the remote manifest if it does not need authenticated fetches","Verify findProviderPresetByBaseUrl(provider.baseUrl) resolves to the expected preset and the endpoint matches its documented API surface","Run the connector through a local manifest where API-key targeting rules are relaxed"],"exampleFix":"// before\n{\"account\":{\"connectors\":[{\"endpoint\":\"https://other-host.example/fetch\"}]}}\n// after\n{\"account\":{\"connectors\":[{\"endpoint\":\"https://api.myprovider.example/fetch\"}]}}","handlingStrategy":"validation","validationCode":"const issue = await validateProviderApiKeyTarget({ apiKey: 'x', endpoint: connector.endpoint, providerName: provider.name });\nif (issue) throw new Error(issue.message);","typeGuard":null,"tryCatchPattern":"catch (e) { if (e instanceof Error && /api key/i.test(e.message)) logManifestIssue(provider.name, e.message); }","preventionTips":["Keep connector endpoints on the provider's own host","Test manifests against a local copy before hosting them remotely"],"tags":["manifest","api-key","security","connector"],"backgroundTag":"credential-target-mismatch","analyzedSha":"99f24806c6a2c660b16e53e95211c517448a6c90","analyzedAt":"2026-08-27T04:11:01.184Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}