{"record":{"id":"90c74966557ce3c0","repo":"Hmbown/CodeWhale","slug":"codewhaleruntimeclient-requires-a-fetch-implementation","errorCode":null,"errorMessage":"CodeWhaleRuntimeClient requires a fetch implementation","messagePattern":"CodeWhaleRuntimeClient requires a fetch implementation","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"npm/runtime-sdk/index.js","lineNumber":28,"sourceCode":"    this.body = options.body;\n  }\n}\n\nexport class RuntimeCapabilityError extends RuntimeApiError {\n  constructor(capability, message, options = {}) {\n    super(message, options);\n    this.name = \"RuntimeCapabilityError\";\n    this.capability = capability;\n  }\n}\n\nexport class CodeWhaleRuntimeClient {\n  constructor(options = {}) {\n    this.baseUrl = normalizeBaseUrl(options.baseUrl ?? DEFAULT_BASE_URL);\n    this.token = options.token ?? null;\n    this.fetchImpl = options.fetch ?? globalThis.fetch;\n    if (typeof this.fetchImpl !== \"function\") {\n      throw new TypeError(\"CodeWhaleRuntimeClient requires a fetch implementation\");\n    }\n  }\n\n  async createFleetRun(spec) {\n    return this.#jsonRequest(\"/v1/fleet/runs\", {\n      method: \"POST\",\n      body: spec,\n      capability: \"fleet_run_create\",\n    });\n  }\n\n  async startFleetRun(runId) {\n    return this.#jsonRequest(`/v1/fleet/runs/${segment(runId)}/start`, {\n      method: \"POST\",\n      capability: \"fleet_run_start\",\n    });\n  }\n","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/npm/runtime-sdk/index.js#L10-L46","documentation":"CodeWhaleRuntimeClient's constructor resolves its fetch implementation from options.fetch or globalThis.fetch and throws a TypeError if neither is a function. This guards environments with no global fetch (old Node, some runtimes).","triggerScenarios":"new CodeWhaleRuntimeClient() is constructed in an environment where globalThis.fetch is undefined and no options.fetch was passed (or a non-function was passed).","commonSituations":"Running on Node < 18 without a fetch polyfill; running in a non-browser embedded runtime; accidentally passing fetch: undefined explicitly; passing a wrongly-named option like fetchFn.","solutions":["Upgrade to Node 18+ (or a runtime with global fetch).","Pass an explicit fetch: new CodeWhaleRuntimeClient({ fetch: require('node-fetch') }).","Verify you pass the option under the exact key `fetch`."],"exampleFix":"// before\nconst client = new CodeWhaleRuntimeClient({ baseUrl });\n// after\nconst client = new CodeWhaleRuntimeClient({ baseUrl, fetch: globalThis.fetch ?? (await import('node-fetch')).default });","handlingStrategy":"type-guard","validationCode":"if (typeof globalThis.fetch !== \"function\" && !options.fetch) { throw new Error(\"Provide options.fetch: this runtime has no global fetch\"); }","typeGuard":"const hasFetch = (o = {}) => typeof (o.fetch ?? globalThis.fetch) === \"function\";\nif (!hasFetch(opts)) throw new Error(\"CodeWhaleRuntimeClient needs a fetch implementation\");","tryCatchPattern":"try { const c = new CodeWhaleRuntimeClient(opts); } catch (e) { if (e instanceof TypeError && e.message.includes(\"fetch implementation\")) { opts = { ...opts, fetch: require('node-fetch') }; } else throw e; }","preventionTips":["Require Node >= 18 or ship a fetch polyfill","Always pass fetch explicitly in non-browser/embedded runtimes","Check option key spelling (fetch, not fetchImpl/fetchFn)"],"tags":["fetch","runtime","constructor","dependency"],"backgroundTag":"missing-dependency","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}