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

  1. Recreate the archive with `tar --format=ustar -cf` so all fields fit standard octal encoding.
  2. Handle GNU base-256 fields: if the high bit of the first byte is set, decode the binary number instead of octal text.
  3. Verify the input is a decompressed tar: gunzip first and check the 512-byte header + 'ustar' magic at offset 257.
  4. 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

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


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/279052d064f71d91. Report an issue: GitHub.