{"record":{"id":"ef61248f88e9963e","repo":"ruvnet/ruflo","slug":"fetchagentcard-no-fetch-implementation-available","errorCode":null,"errorMessage":"fetchAgentCard: no fetch implementation available","messagePattern":"fetchAgentCard: no fetch implementation available","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/plugin-agent-federation/src/a2a/consume.ts","lineNumber":49,"sourceCode":" * URL) gets the A2A well-known path appended; anything already pointing at a\n * JSON document is used as-is.\n */\nexport function resolveAgentCardUrl(baseOrCardUrl: string): string {\n  const url = new URL(baseOrCardUrl);\n  if (url.pathname === '/' || url.pathname === '') {\n    url.pathname = A2A_WELL_KNOWN_PATH;\n  }\n  return url.toString();\n}\n\n/** Fetch and structurally validate a remote A2A Agent Card. */\nexport async function fetchAgentCard(\n  baseOrCardUrl: string,\n  options: FetchAgentCardOptions = {},\n): Promise<FetchAgentCardResult> {\n  const fetchImpl = options.fetchImpl ?? globalThis.fetch;\n  if (typeof fetchImpl !== 'function') {\n    throw new Error('fetchAgentCard: no fetch implementation available');\n  }\n  const sourceUrl = resolveAgentCardUrl(baseOrCardUrl);\n  const maxBytes = options.maxBytes ?? 256 * 1024;\n\n  const controller = new AbortController();\n  const timer = setTimeout(() => controller.abort(), options.timeoutMs ?? 10_000);\n  let text: string;\n  try {\n    const res = await fetchImpl(sourceUrl, {\n      signal: controller.signal,\n      headers: { accept: 'application/json' },\n    });\n    if (!res.ok) {\n      throw new Error(`fetchAgentCard: ${sourceUrl} returned HTTP ${res.status}`);\n    }\n    text = await res.text();\n  } finally {\n    clearTimeout(timer);","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/plugin-agent-federation/src/a2a/consume.ts#L31-L67","documentation":"fetchAgentCard() needs an HTTP client: options.fetchImpl if provided, otherwise the global globalThis.fetch. When neither is a function it refuses to start the request. This targets runtimes without a built-in WHATWG fetch (Node.js below 18, older jsdom test setups, some bundler/edge configurations).","triggerScenarios":"Running on Node 16 or earlier where globalThis.fetch is undefined; test environments (older jsdom) that do not install fetch; bundlers that tree-shake or alias the global away; passing options.fetchImpl that is not a function (e.g. a module object).","commonSituations":"CI images pinned to old Node LTS versions; Electron renderer or sandboxed contexts without fetch; code reused across Node and restricted runtimes.","solutions":["Pass an implementation explicitly: fetchAgentCard(url, { fetchImpl }) using undici's or node-fetch's fetch","Upgrade to Node 18+ or a runtime that ships WHATWG fetch","In tests, inject a stub fetchImpl instead of relying on the global","If you import a fetch polyfill, make sure it runs before this module is used"],"exampleFix":"// before\nawait fetchAgentCard('https://peer.example');\n// after\nimport { fetch as undiciFetch } from 'undici';\nawait fetchAgentCard('https://peer.example', { fetchImpl: undiciFetch });","handlingStrategy":"validation","validationCode":"const fetchImpl =\n  typeof globalThis.fetch === 'function'\n    ? globalThis.fetch.bind(globalThis)\n    : (await import('undici')).fetch;\nawait fetchAgentCard(url, { fetchImpl });","typeGuard":"function hasGlobalFetch(): boolean {\n  return typeof globalThis.fetch === 'function';\n}","tryCatchPattern":null,"preventionTips":["Run on Node 18+ or inject undici/node-fetch explicitly","In tests, always pass a stub fetchImpl rather than relying on the global","Check runtime requirements once at process start and fail with a clear message","Avoid relying on ambient globals in bundled code"],"tags":["fetch","runtime","nodejs","a2a"],"backgroundTag":"fetch-is-not-defined","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}