can1357/oh-my-pi · error · ArchiveError
Invalid RAR5 UTF-8 member name
Error message
Invalid RAR5 UTF-8 member name
What it means
The member's file name bytes are decoded as UTF-8 (RAR5 stores names in UTF-8). If the byte range fails UTF-8 validation, the library throws this ArchiveError rather than emitting a record with a corrupted path — usually a sign the file is not a genuine RAR5 archive or is corrupted.
Source
Thrown at packages/utils/src/ar/rar.ts:375
let version = compression & 0x3f;
if (version === 1 && (compression & 0x100000) !== 0) version = 0;
const solid = (compression & 0x40) !== 0;
const method = (compression >>> 7) & 7;
const dictionaryPower = (compression >>> 10) & 0x1f;
let dictionarySize = 128 * 1024 * 2 ** dictionaryPower;
if ((compression & 0x3f) === 1) dictionarySize += (dictionarySize * ((compression >>> 15) & 0x1f)) / 32;
if (!Number.isSafeInteger(dictionarySize) || dictionarySize > options.limits.maxInMemorySize) {
throw new ArchiveError(`RAR5 dictionary is too large (${dictionarySize} bytes)`);
}
const hostOs = readVint(bytes, cursor, extraStart, "host OS");
const nameSize = readVint(bytes, cursor, extraStart, "file name size");
assertArchivePathBytes(nameSize, "member path", options.limits.maxPathBytes);
need(cursor.offset, nameSize, extraStart, "RAR5 file name");
let rawPath: string;
try {
rawPath = UTF8.decode(bytes.subarray(cursor.offset, cursor.offset + nameSize));
} catch {
throw new ArchiveError("Invalid RAR5 UTF-8 member name");
}
cursor.offset += nameSize;
let linkTarget: string | undefined;
for (const extra of readExtraRecords(bytes, extraStart, headerEnd)) {
const extraCursor = { offset: extra.start };
if (extra.type === 1) throw new ArchiveError(`Encrypted RAR5 member '${rawPath}' is not supported`);
if (extra.type === 3) {
const timeFlags = readVint(bytes, extraCursor, extra.end, "time flags");
if ((timeFlags & 2) !== 0) {
if ((timeFlags & 1) !== 0) {
need(extraCursor.offset, 4, extra.end, "Unix modification time");
mtimeMs = readUInt32LE(bytes, extraCursor.offset) * 1000;
} else {
need(extraCursor.offset, 8, extra.end, "Windows modification time");
mtimeMs = filetimeMs(bytes, extraCursor.offset);
}
}
} else if (extra.type === 5) {View on GitHub (pinned to 9690622007)
Solutions
- Verify the archive integrity (`unrar t archive.rar`) and re-download/re-extract if corrupt
- Confirm the file is really RAR5 (`file archive.rar`) and not a renamed archive of another format
- If it is a genuine corrupted archive, repair with WinRAR's repair function or `rar r`
Defensive patterns
Strategy: try-catch
Try / catch
try {
const records = readRar(bytes);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes('Invalid RAR5 UTF-8')) {
throw new Error('Archive is corrupt or not a valid RAR5 file');
} else throw err;
} Prevention
- Verify checksums of downloaded archives before parsing
- Run `unrar t` as a pre-flight integrity check
- Treat this error as a corruption signal, not a recoverable path issue
When it happens
Trigger: Decoding bytes.subarray(name bytes) with UTF8.decode throws — non-UTF-8 name bytes in a file header, corrupt/truncated data misdetected as RAR5, or a forged header with an invalid nameSize pointing at binary data.
Common situations: Corrupted downloads; files with a RAR5-like signature but different inner format; archives damaged in transfer; malicious files crafted to break parsers.
Related errors
- Invalid RAR5 UTF-8 link target
- InvalidArg
- entry name contains NUL
- Persistent credential block store ${store} is unavailable af
- Upload filename is invalid
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/1d4cc82cf4f29905.
Report an issue: GitHub.