{"record":{"id":"46023e683306b2f9","repo":"coleam00/Archon","slug":"provider-s-entry-agents-join-declare-cre","errorCode":null,"errorMessage":"Provider(s) ${entry.agents.join(', ')} declare credential vendor '${entry.vendor}' (api_key) but the delivery map has no rule for it.","messagePattern":"Provider\\(s\\) (.+?) declare credential vendor '(.+?)' \\(api_key\\) but the delivery map has no rule for it\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"packages/core/src/credentials/catalog.ts","lineNumber":65,"sourceCode":"      const existing = catalog.get(spec.vendor);\n      if (existing) {\n        existing.agents.push(reg.id);\n        for (const k of spec.kinds) {\n          if (!existing.kinds.includes(k)) existing.kinds.push(k);\n        }\n      } else {\n        catalog.set(spec.vendor, {\n          vendor: spec.vendor,\n          displayName: spec.displayName,\n          kinds: [...spec.kinds],\n          agents: [reg.id],\n        });\n      }\n    }\n  }\n  for (const entry of catalog.values()) {\n    if (entry.kinds.includes('api_key') && !KNOWN_VENDORS.has(entry.vendor)) {\n      throw new Error(\n        `Provider(s) ${entry.agents.join(', ')} declare credential vendor '${entry.vendor}' ` +\n          '(api_key) but the delivery map has no rule for it.'\n      );\n    }\n  }\n  return catalog;\n}\n\n/** Sorted vendor ids a user can connect an API key for. */\nexport function listConnectableVendors(): string[] {\n  return [...getVendorCatalog().values()]\n    .filter(e => e.kinds.includes('api_key'))\n    .map(e => e.vendor)\n    .sort();\n}\n\n/** Whether `id` (vendor-canonical or legacy agent-keyed) is API-key connectable. */\nexport function isConnectableVendor(id: string): boolean {","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/coleam00/Archon/blob/0773b9745896ef0612e709c80845a0f7db315b19/packages/core/src/credentials/catalog.ts#L47-L83","documentation":"Thrown by getVendorCatalog when a registered provider statically declares an api_key credential vendor that the delivery map (KNOWN_VENDORS, derived from PI_PROVIDER_ENV_VARS) has no rule for. This is a deliberate fail-loud registration-time invariant: a key could be connected but never delivered to the agent, so the catalog refuses to build rather than silently offering an undeliverable credential.","triggerScenarios":"Booting the server or calling getVendorCatalog/listConnectableVendors after registering a provider whose `credentials.specs` includes a vendor id absent from PI_PROVIDER_ENV_VARS — typically after adding a new community provider, renaming a vendor id, or a pi-ai SDK upgrade that dropped/regenerated the env-var map.","commonSituations":"Developing a custom provider plugin and misspelling the vendor id; upgrading @earendil-works/pi-ai so the generated PI_PROVIDER_ENV_VARS loses a key; moving a vendor to ambient-only in the map while a registration still declares api_key.","solutions":["Add a delivery rule: ensure the vendor id has an entry in PI_PROVIDER_ENV_VARS (@archon/providers, regenerated via `bun run check:pi-vendor-map`) so KNOWN_VENDORS includes it.","Fix the provider registration: correct the vendor id in the provider's `credentials.specs` to match a known vendor.","If the vendor is genuinely ambient-only, change the spec's kinds from 'api_key' to 'ambient' instead of declaring an undeliverable key kind.","Run `bun run check:pi-vendor-map` to confirm the generated vendor map and registrations agree."],"exampleFix":"// before (provider registration)\nspecs: [{ vendor: 'anthropicx', kinds: ['api_key'] }]\n// after\nspecs: [{ vendor: 'anthropic', kinds: ['api_key'] }]","handlingStrategy":"validation","validationCode":"import { KNOWN_VENDORS } from './delivery';\nfunction validateRegistration(specs: { vendor: string; kinds: string[] }[]): string | null {\n  for (const s of specs)\n    if (s.kinds.includes('api_key') && !KNOWN_VENDORS.has(s.vendor))\n      return `vendor '${s.vendor}' has no delivery rule`;\n  return null;\n}","typeGuard":null,"tryCatchPattern":"try {\n  const catalog = getVendorCatalog();\n} catch (e) {\n  const m = /declare credential vendor '([^']+)'/.exec((e as Error).message);\n  if (m) throw new Error(`Fix provider registration or add delivery rule for '${m[1]}'`, { cause: e });\n  throw e;\n}","preventionTips":["Derive vendor ids from a shared constant shared between registration and the env-var map instead of string literals.","Run `bun run check:pi-vendor-map` in CI to catch drift between registrations and the generated map.","Add a unit test that builds the catalog over all builtin + community providers.","Never declare 'api_key' kind for ambient-only vendors."],"tags":["credentials","registration","provider","invariant"],"backgroundTag":"unknown-credential-vendor","analyzedSha":"0773b9745896ef0612e709c80845a0f7db315b19","analyzedAt":"2026-09-01T02:28:07.064Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}