can1357/oh-my-pi · error · Error
Invalid tar octal value: ${value}
Error message
Invalid tar octal value: ${value} What it means
readTarOctal() reads a tar header field as a NUL-padded octal ASCII string and parses it with parseInt(value, 8). If the field contains characters that are not valid octal (so the parse yields NaN/Infinity), it throws this error naming the raw value. This indicates the buffer is not a well-formed tar header at the expected offset.
Source
Thrown at packages/natives/native/loader-state.js:449
null
);
}
return embeddedAddon.files.find(file => file.variant === "baseline") || null;
}
function readTarString(buffer, offset, length) {
const end = Math.min(offset + length, buffer.length);
let stringEnd = offset;
while (stringEnd < end && buffer[stringEnd] !== 0) stringEnd++;
return buffer.toString("utf8", offset, stringEnd);
}
function readTarOctal(buffer, offset, length) {
const value = readTarString(buffer, offset, length).trim();
if (!value) return 0;
const parsed = Number.parseInt(value, 8);
if (!Number.isFinite(parsed)) {
throw new Error(`Invalid tar octal value: ${value}`);
}
return parsed;
}
function isZeroTarBlock(buffer, offset) {
for (let index = 0; index < 512; index++) {
if (buffer[offset + index] !== 0) return false;
}
return true;
}
function getTarEntryName(header) {
const name = readTarString(header, 0, 100);
const prefix = readTarString(header, 345, 155);
return prefix ? `${prefix}/${name}` : name;
}
function isSafeEmbeddedAddonFilename(filename) {View on GitHub (pinned to 9690622007)
Solutions
- Recreate the archive with `tar --format=ustar -cf` so all fields fit standard octal encoding.
- Handle GNU base-256 fields: if the high bit of the first byte is set, decode the binary number instead of octal text.
- Verify the input is a decompressed tar: gunzip first and check the 512-byte header + 'ustar' magic at offset 257.
- Confirm offsets/lengths against the tar header layout (size at 124, mtime at 136, etc.).
Example fix
// before
const parsed = Number.parseInt(value, 8);
if (!Number.isFinite(parsed)) throw new Error(`Invalid tar octal value: ${value}`);
// after
function readNumericField(buffer, offset, length) {
if (buffer[offset] & 0x80) {
// GNU base-256 encoding (large files)
let result = buffer[offset] & 0x7f;
for (let i = offset + 1; i < offset + length; i++) result = result * 256 + buffer[i];
return result;
}
const value = readTarString(buffer, offset, length).trim();
if (!value) return 0;
const parsed = Number.parseInt(value, 8);
if (!Number.isFinite(parsed)) throw new Error(`Invalid tar octal value: ${value}`);
return parsed;
} Defensive patterns
Strategy: validation
Validate before calling
function isTarBuffer(buf) {
return buf.length >= 512 && buf.subarray(257, 262).toString('utf8') === 'ustar';
}
function usesBase256(buf, offset) {
return (buf[offset] & 0x80) !== 0; // GNU binary numeric field
}
if (!isTarBuffer(buffer)) throw new Error('Not a tar archive (missing ustar magic)');
if (usesBase256(buffer, 124)) throw new Error('Entry uses GNU base-256 size; decode binary field'); Type guard
function isOctalField(buf, offset, length) {
for (let i = offset; i < offset + length; i++) {
const b = buf[i];
if (b === 0) return true;
if (b < 0x30 || b > 0x37) return false;
}
return true;
} Try / catch
try {
const size = readTarOctal(header, 124, 12);
} catch (err) {
if (err instanceof Error && err.message.startsWith('Invalid tar octal value')) {
// likely GNU base-256 encoding (huge file) or bad offset — decode binary field
const size = readBase256(header, 124, 12);
} else throw err;
} Prevention
- Create archives with --format=ustar to keep all fields octal-representable
- Gunzip before parsing — never feed compressed bytes to a tar parser
- Check the 'ustar' magic at offset 257 before reading header fields
- Handle GNU base-256 numeric fields for entries larger than 8 GiB
When it happens
Trigger: Calling readTarOctal(buffer, offset, length) on a buffer whose field at offset contains non-octal text — e.g. GNU tar base-256 (binary) size encoding for files >8GB, a non-tar file, or a misaligned offset.
Common situations: Extracting archives with entries larger than 8 GiB (old-style octal fields can't represent them so writers use base-256), parsing a gzip stream without decompressing first, reading a truncated/corrupted archive, or hard-coded offsets that don't match the header layout.
Related errors
- Truncated embedded addon archive entry: ${filename}
- Archive member '${formatArchivePathForError(memberPath)}' is
- Archive member '${formatArchivePathForError(memberPath)}' ha
- Claude session ${info.id} contains no readable records
- Unsafe embedded addon archive entry: ${filename}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/279052d064f71d91.
Report an issue: GitHub.