{"record":{"id":"4f65b072257b6cfa","repo":"evanw/esbuild","slug":"the-input-to-transform-must-be-a-string-or-a-uin","errorCode":null,"errorMessage":"The input to \"transform\" must be a string or a Uint8Array","messagePattern":"The input to \"transform\" must be a string or a Uint8Array","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/shared/common.ts","lineNumber":710,"sourceCode":"    // Ideally the \"transform()\" API would be faster than calling \"build()\"\n    // since it doesn't need to touch the file system. However, performance\n    // measurements with large files on macOS indicate that sending the data\n    // over the stdio pipe can be 2x slower than just using a temporary file.\n    //\n    // This appears to be an OS limitation. Both the JavaScript and Go code\n    // are using large buffers but the pipe only writes data in 8kb chunks.\n    // An investigation seems to indicate that this number is hard-coded into\n    // the OS source code. Presumably files are faster because the OS uses\n    // a larger chunk size, or maybe even reads everything in one syscall.\n    //\n    // The cross-over size where this starts to be faster is around 1mb on\n    // my machine. In that case, this code tries to use a temporary file if\n    // possible but falls back to sending the data over the stdio pipe if\n    // that doesn't work.\n    let start = (inputPath: string | null) => {\n      try {\n        if (typeof input !== 'string' && !(input instanceof Uint8Array))\n          throw new Error('The input to \"transform\" must be a string or a Uint8Array')\n        let {\n          flags,\n          mangleCache,\n        } = flagsForTransformOptions(callName, options, isTTY, transformLogLevelDefault)\n        let request: protocol.TransformRequest = {\n          command: 'transform',\n          flags,\n          inputFS: inputPath !== null,\n          input: inputPath !== null ? protocol.encodeUTF8(inputPath)\n            : typeof input === 'string' ? protocol.encodeUTF8(input)\n              : input,\n        }\n        if (mangleCache) request.mangleCache = mangleCache\n        sendRequest<protocol.TransformRequest, protocol.TransformResponse>(refs, request, (error, response) => {\n          if (error) return callback(new Error(error), null)\n          let errors = replaceDetailsInMessages(response!.errors, details)\n          let warnings = replaceDetailsInMessages(response!.warnings, details)\n          let outstanding = 1","sourceCodeStart":692,"sourceCodeEnd":728,"githubUrl":"https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/lib/shared/common.ts#L692-L728","documentation":"transform() only accepts source code as a string or a Uint8Array; anything else is rejected up front at lib/shared/common.ts:710 before options are even parsed. This is a hard precondition because the input is sent to the binary as bytes.","triggerScenarios":"Calling `transform(null)`, `transform(undefined)`, `transform(123)`, `transform({ code: '...' })`, `transform(Buffer?)` in an environment where the value is not a string/Uint8Array, or forgetting to read a file's contents before transforming.","commonSituations":"Passing an options object as the first argument by mistake; passing a path string expecting esbuild to read the file (use build() for that); async code that resolved to undefined; receiving data from an API that returned JSON instead of text.","solutions":["Ensure the first argument is a string or Uint8Array (read file contents first with fs.readFileSync if needed).","If you have a path, use build({ entryPoints: [path] }) instead of transform().","Add a type guard before calling to surface a clearer error in your own code."],"exampleFix":"// before\nconst code = fs.readFile('app.ts') // forgot await/callback -> undefined\nawait esbuild.transform(code, { loader: 'ts' })\n\n// after\nconst code = await fs.promises.readFile('app.ts', 'utf8')\nawait esbuild.transform(code, { loader: 'ts' })","handlingStrategy":"type-guard","validationCode":"function ensureTransformInput(input) {\n  if (typeof input !== 'string' && !(input instanceof Uint8Array)) {\n    throw new TypeError('transform input must be a string or Uint8Array')\n  }\n  return input\n}\nawait esbuild.transform(ensureTransformInput(maybeCode), { loader: 'ts' })","typeGuard":"function isTransformInput(v): v is string | Uint8Array {\n  return typeof v === 'string' || v instanceof Uint8Array\n}\nif (!isTransformInput(input)) throw new TypeError('invalid transform input')","tryCatchPattern":null,"preventionTips":["Always read file contents (fs.readFileSync/readFile) before passing to transform().","For path-based input, use build({ entryPoints: [path] }) instead of transform().","Add a type guard so a clearer error surfaces from your own code before reaching esbuild."],"tags":["api","validation","transform","type-mismatch"],"backgroundTag":null,"analyzedSha":"f6058f8364fe7ab91ca57a83e02577ed74c9cae4","analyzedAt":"2026-08-09T18:37:22.223Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}