evanw/esbuild · error · Error
The input to "transform" must be a string or a Uint8Array
Error message
The input to "transform" must be a string or a Uint8Array
What it means
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.
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.
Example fix
// before
const code = fs.readFile('app.ts') // forgot await/callback -> undefined
await esbuild.transform(code, { loader: 'ts' })
// after
const code = await fs.promises.readFile('app.ts', 'utf8')
await esbuild.transform(code, { loader: 'ts' }) Defensive patterns
Strategy: type-guard
Validate before calling
function ensureTransformInput(input) {
if (typeof input !== 'string' && !(input instanceof Uint8Array)) {
throw new TypeError('transform input must be a string or Uint8Array')
}
return input
}
await esbuild.transform(ensureTransformInput(maybeCode), { loader: 'ts' }) Type guard
function isTransformInput(v): v is string | Uint8Array {
return typeof v === 'string' || v instanceof Uint8Array
}
if (!isTransformInput(input)) throw new TypeError('invalid transform input') Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Expected value for supported
- Expected value for to be a string, got instead
- Missing "kind" in () call
- Missing second argument in
- must be
AI-assisted analysis of evanw/esbuild@f6058f8364 (2026-08-09).
Data as JSON: /api/errors/4f65b072257b6cfa.
Report an issue: GitHub.
Appendix: source
Thrown at lib/shared/common.ts:710
// Ideally the "transform()" API would be faster than calling "build()"
// since it doesn't need to touch the file system. However, performance
// measurements with large files on macOS indicate that sending the data
// over the stdio pipe can be 2x slower than just using a temporary file.
//
// This appears to be an OS limitation. Both the JavaScript and Go code
// are using large buffers but the pipe only writes data in 8kb chunks.
// An investigation seems to indicate that this number is hard-coded into
// the OS source code. Presumably files are faster because the OS uses
// a larger chunk size, or maybe even reads everything in one syscall.
//
// The cross-over size where this starts to be faster is around 1mb on
// my machine. In that case, this code tries to use a temporary file if
// possible but falls back to sending the data over the stdio pipe if
// that doesn't work.
let start = (inputPath: string | null) => {
try {
if (typeof input !== 'string' && !(input instanceof Uint8Array))
throw new Error('The input to "transform" must be a string or a Uint8Array')
let {
flags,
mangleCache,
} = flagsForTransformOptions(callName, options, isTTY, transformLogLevelDefault)
let request: protocol.TransformRequest = {
command: 'transform',
flags,
inputFS: inputPath !== null,
input: inputPath !== null ? protocol.encodeUTF8(inputPath)
: typeof input === 'string' ? protocol.encodeUTF8(input)
: input,
}
if (mangleCache) request.mangleCache = mangleCache
sendRequest<protocol.TransformRequest, protocol.TransformResponse>(refs, request, (error, response) => {
if (error) return callback(new Error(error), null)
let errors = replaceDetailsInMessages(response!.errors, details)
let warnings = replaceDetailsInMessages(response!.warnings, details)
let outstanding = 1View on GitHub (pinned to f6058f8364)