expo/expo · error · RangeError
Unknown encoding: ${label} (normalized: ${normalizedLabel})
Error message
Unknown encoding: ${label} (normalized: ${normalizedLabel}) What it means
expo's TextDecoder polyfill intentionally supports only the UTF-8 family of labels (utf-8, utf8, unicode20utf8, x-unicode20utf8), matching the WHATWG encoding standard's must-support encoding. Any other label throws a RangeError with both the original and the normalized label included, mirroring the spec's RangeError for unknown encodings.
Source
Thrown at packages/expo/src/winter/TextDecoder.ts:24
ignoreBOM: boolean;
fatal: boolean;
bomSeen: boolean;
pending: Uint8Array;
streaming: boolean;
}
function assertValidUTF8Label(label: unknown): void {
const normalizedLabel = String(label).trim().toLowerCase();
switch (normalizedLabel) {
case 'unicode-1-1-utf-8':
case 'unicode11utf8':
case 'unicode20utf8':
case 'utf-8':
case 'utf8':
case 'x-unicode20utf8':
return;
default:
throw new RangeError(`Unknown encoding: ${label} (normalized: ${normalizedLabel})`);
}
}
function normalizeBytes(input: ArrayBuffer | ArrayBufferView | undefined): Uint8Array {
if (input === undefined) {
return EMPTY_BYTES;
} else if (input instanceof Uint8Array) {
return input;
} else if (ArrayBuffer.isView(input)) {
return new Uint8Array(input.buffer, input.byteOffset, input.byteLength);
} else if (
(input[Symbol.toStringTag] as string) === 'ArrayBuffer' ||
(input[Symbol.toStringTag] as string) === 'SharedArrayBuffer'
) {
return new Uint8Array(input as ArrayBuffer);
} else {
throw new TypeError('The input must be an ArrayBuffer or ArrayBufferView');
}View on GitHub (pinned to da586c407b)
Solutions
- Decode as UTF-8: `new TextDecoder('utf-8')` - convert the data to UTF-8 upstream if it is not already.
- Transcode the bytes to UTF-8 before decoding (server-side or with a dedicated converter).
- On hosts with a native full TextDecoder (browsers, Node), use globalThis.TextDecoder instead of the polyfill.
Example fix
// before
const dec = new TextDecoder('utf-16le'); // RangeError: Unknown encoding
// after
const dec = new TextDecoder('utf-8'); // only UTF-8 is supported Defensive patterns
Strategy: validation
Validate before calling
const UTF8_LABELS = new Set(['utf-8', 'utf8', 'unicode20utf8', 'x-unicode20utf8']);
function isSupportedLabel(label: string): boolean {
return UTF8_LABELS.has(label.trim().toLowerCase().replace(/[-_]/g, '')); // rough normalize
}
if (!isSupportedLabel(label)) label = 'utf-8'; Try / catch
try {
decoder = new TextDecoder(label);
} catch (error) {
if (error instanceof RangeError && error.message.startsWith('Unknown encoding')) {
decoder = new TextDecoder('utf-8'); // fall back to UTF-8
} else throw error;
} Prevention
- Standardize on UTF-8 end to end so the default constructor is all you need.
- Transcode non-UTF-8 data upstream (server side) rather than at the decoder.
- Use the host's native TextDecoder where full encoding support is required.
When it happens
Trigger: `new TextDecoder('utf-16le')`, `new TextDecoder('iso-8859-1')`, `new TextDecoder('windows-1252')` - any label that does not normalize to a UTF-8 alias - on a platform using expo's TextDecoder (e.g. React Native runtimes without a native TextDecoder).
Common situations: Porting web code that decodes UTF-16 response bodies; libraries assuming Node's full-ICU decoder is present; labels taken verbatim from a server's charset header.
Related errors
- Decoder error
- Buffer.from: unsupported encoding ${enc}
- Buffer.toString: unsupported encoding ${enc}
- The input must be an ArrayBuffer or ArrayBufferView
- Second argument of TextDecoder must be undefined or an objec
AI-assisted analysis of expo/expo@da586c407b (2026-08-23).
Data as JSON: /api/errors/1176637ea3666f4b.
Report an issue: GitHub.