{"record":{"id":"bf29acf548b6b9d0","repo":"nodejs/node","slug":"und-err-invalid-return-value-bf29ac","errorCode":"UND_ERR_INVALID_RETURN_VALUE","errorMessage":"expected Writable","messagePattern":"expected Writable","errorType":"validation","errorClass":"InvalidReturnValueError","httpStatus":null,"severity":"error","filePath":"deps/undici/src/lib/api/api-stream.js","lineNumber":164,"sourceCode":"\n    if (factory === null) {\n      return\n    }\n\n    const res = this.runInAsyncScope(factory, null, {\n      statusCode,\n      headers: responseHeaderData,\n      opaque,\n      context\n    })\n\n    if (\n      !res ||\n      typeof res.write !== 'function' ||\n      typeof res.end !== 'function' ||\n      typeof res.on !== 'function'\n    ) {\n      throw new InvalidReturnValueError('expected Writable')\n    }\n\n    trackWritableLifecycle(res, (err, fromErrorEvent) => {\n      const { callback, res, opaque, trailers, abort } = this\n\n      this.res = null\n      if (err || !res?.readable) {\n        util.destroy(res, fromErrorEvent ? undefined : err)\n      }\n\n      this.callback = null\n      this.runInAsyncScope(callback, null, err || null, { opaque, trailers })\n\n      if (err) {\n        abort(err)\n      }\n    })\n","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/undici/src/lib/api/api-stream.js#L146-L182","documentation":"Thrown by undici's StreamHandler (InvalidReturnValueError, code UND_ERR_INVALID_RETURN_VALUE) at response time when the factory function returns a value that is missing .write, .end, or .on. The factory must return a Node.js Writable stream so the response body can be pumped into it. Returning null, a string, a Promise, or a non-stream object triggers this.","triggerScenarios":"Factory returns undefined (e.g. forgot return), returns a Promise<Writable> (async factory), returns an object literal, or returns a web ReadableStream/WritableStream (WHATWG) instead of a Node stream.","commonSituations":"Async factory functions whose returned stream is awaited implicitly; returning fs.createWriteStream conditionally such that some branches return nothing; mixing up Web Streams API with Node streams.","solutions":["Ensure the factory is synchronous and returns a Node Writable with write/end/on (e.g. fs.createWriteStream, stream.Writable, http.ServerResponse).","If the factory must be async, create the Writable synchronously inside it and resolve setup asynchronously rather than returning a Promise.","Confirm the returned object is not a WHATWG WritableStream — convert via stream.Writable.fromWeb() if needed."],"exampleFix":"// before\nstream(opts, async ({ statusCode }) => fs.createWriteStream(path), cb) // async -> Promise\n\n// after\nstream(opts, ({ statusCode }) => fs.createWriteStream(path), cb)","handlingStrategy":"try-catch","validationCode":"function wrapFactory(f) {\n  return (ctx) => {\n    const res = f(ctx)\n    if (!res || typeof res.write !== 'function' || typeof res.end !== 'function' || typeof res.on !== 'function') {\n      throw new Error('factory must return a Node Writable')\n    }\n    return res\n  }\n}\n// stream(opts, wrapFactory(myFactory), cb)","typeGuard":"function isNodeWritable(v) {\n  return !!v && typeof v.write === 'function' && typeof v.end === 'function' && typeof v.on === 'function'\n}","tryCatchPattern":"try {\n  stream(opts, factory, cb)\n} catch (e) {\n  if (e.code === 'UND_ERR_INVALID_RETURN_VALUE') {\n    // factory returned a non-Writable; fix it to return a Node Writable and retry\n  } else throw e\n}","preventionTips":["Keep the factory synchronous and always return a Node Writable (fs.createWriteStream, stream.Writable, http.ServerResponse).","Never return a Promise or a WHATWG WritableStream from the factory.","Add a unit test asserting the factory's return value passes the write/end/on shape check."],"tags":["undici","stream","writable","return-value","runtime"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}