drizzle-team/drizzle-orm · critical · Error
TextDecoder is not available. Please provide either Buffer…
Error message
TextDecoder is not available. Please provide either Buffer or TextDecoder polyfill.
What it means
Thrown by normalizeFieldValue in the LibSQL session (line 324) when a returned value is an ArrayBuffer but neither Buffer (Node) nor TextDecoder (browser/modern runtimes) is available to decode it. This is purely an environment capability gap - the runtime lacks the global APIs Drizzle needs to materialize binary column data.
Solutions
- Add a TextDecoder polyfill to your runtime/bundle (e.g. fast-text-encoding) so globalThis.TextDecoder is defined.
- If on Node, ensure Buffer is available - avoid bundlers that strip node:buffer.
- Run on a runtime that ships TextDecoder natively (modern browsers, Node 18+, Cloudflare Workers, Deno).
- Avoid selecting BLOB columns if you cannot provide a decoder, or cast them to text in SQL.
Example fix
// before - runtime lacks TextDecoder
// Error: TextDecoder is not available...
// after - install a polyfill before any query
import 'fast-text-encoding'; // adds global TextDecoder
// or in entry:
globalThis.TextDecoder = globalThis.TextDecoder || (await import('util')).TextDecoder;
await db.select().from(files).where(eq(files.id, id)); Defensive patterns
Strategy: validation
Validate before calling
// Ensure a decoder exists before running queries
const hasDecoder = typeof Buffer !== 'undefined' || typeof TextDecoder !== 'undefined';
if (!hasDecoder) {
throw new Error('Install a TextDecoder polyfill (e.g. fast-text-encoding).');
} Type guard
function hasBinaryDecoder(): boolean {
return typeof Buffer !== 'undefined' || typeof TextDecoder !== 'undefined';
} Prevention
- Run on a runtime with TextDecoder (Node 18+, modern browsers, Deno, CF Workers).
- Polyfill TextDecoder in stripped runtimes before importing drizzle-orm.
- Avoid bundler settings that strip node:buffer.
- Cast BLOB columns to text in SQL if you can't decode binary.
When it happens
Trigger: A LibSQL query returns a binary/blob column whose value arrives as ArrayBuffer, and the JS runtime exposes neither global Buffer nor global TextDecoder. Common in stripped-down or non-standard runtimes.
Common situations: Running Drizzle + LibSQL on an edge runtime or custom embedded JS engine that lacks TextDecoder; bundling with aggressive polyfill stripping that removes Node Buffer; older environments without TextDecoder support.
Related errors
- TextDecoder is not available. Please provide either Buffer…
- Failed query: params
- Cannot execute a query on a query builder. Please use a…
- Failed query: params
- Method not implemented.
AI-assisted analysis of drizzle-team/drizzle-orm@b7862528fd (2026-08-03).
Data as JSON: /api/errors/9860629a1ca2a5d8.
Report an issue: GitHub.
Appendix: source
Thrown at drizzle-orm/src/libsql/session.ts:324
if (Object.prototype.propertyIsEnumerable.call(obj, key)) {
acc[key] = obj[key];
}
return acc;
}, {});
}
function normalizeFieldValue(value: unknown) {
if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { // eslint-disable-line no-instanceof/no-instanceof
if (typeof Buffer !== 'undefined') {
if (!(value instanceof Buffer)) { // eslint-disable-line no-instanceof/no-instanceof
return Buffer.from(value);
}
return value;
}
if (typeof TextDecoder !== 'undefined') {
return new TextDecoder().decode(value);
}
throw new Error('TextDecoder is not available. Please provide either Buffer or TextDecoder polyfill.');
}
return value;
}
View on GitHub (pinned to b7862528fd)