Yeachan-Heo/oh-my-codex · error · Error

archive_format_unsupported

archive_format_unsupported

Error message

[native-assets] archive_format_unsupported: ${archivePath}

What it means

The native-assets archive inspector only supports .tar.xz, .tar.gz, and .zip archives, detected purely by file extension (case-insensitive). archiveFormat throws archive_format_unsupported when the path matches none of those suffixes, before any file I/O occurs. Rename the file (or repackage it) so the extension reflects a supported format.

Source

Thrown at src/native-assets/archive.ts:35

  /** Original archive member name, retained for diagnostics and exact extraction. */
  rawName: string;
  /** Safe, separator-normalized logical member name. */
  normalizedName: string;
  /** @deprecated Use normalizedName. */
  path: string;
  type: NativeArchiveEntryType;
  size: number;
}

function archiveError(code: string, detail: string): Error {
  return new Error(`[native-assets] ${code}: ${detail}`);
}

function archiveFormat(archivePath: string): 'tar.xz' | 'tar.gz' | 'zip' {
  if (/\.tar\.xz$/i.test(archivePath)) return 'tar.xz';
  if (/\.tar\.gz$/i.test(archivePath)) return 'tar.gz';
  if (/\.zip$/i.test(archivePath)) return 'zip';
  throw archiveError('archive_format_unsupported', archivePath);
}

function entry(rawName: string, type: NativeArchiveEntryType, size: number): NativeArchiveEntry {
  if (!Number.isSafeInteger(size) || size < 0) throw archiveError('archive_inspection_failed', `invalid entry size: ${rawName}`);
  const normalizedName = normalizeNativeArchivePath(rawName, type);
  return { rawName, normalizedName, path: normalizedName, type, size };
}

async function tarInput(archivePath: string, format: 'tar.xz' | 'tar.gz'): Promise<Readable> {
  try {
    const archive = readFileSync(archivePath);
    return Readable.from(format === 'tar.gz' ? gunzipSync(archive) : await decompress(archive));
  } catch (error) {
    throw archiveError('archive_inspection_failed', error instanceof Error ? error.message : archivePath);
  }
}

async function inspectTar(archivePath: string, format: 'tar.xz' | 'tar.gz'): Promise<NativeArchiveEntry[]> {

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Rename .tgz to .tar.gz (or repackage) since the checker matches only literal suffixes
  2. Repackage unsupported formats (7z, bz2, plain tar) into zip/tar.gz/tar.xz
  3. Validate the extension in caller code before invoking the inspector

Example fix

// before
const entries = await inspectArchive(path.join(dir, 'bundle.tgz')); // throws archive_format_unsupported

// after
const fixed = path.join(dir, 'bundle.tar.gz');
await fs.rename(path.join(dir, 'bundle.tgz'), fixed);
const entries = await inspectArchive(fixed);
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED = /\.(tar\.xz|tar\.gz|zip)$/i;
if (!SUPPORTED.test(archivePath)) throw new Error(`Unsupported archive: ${archivePath}`);
// normalize common alias
if (/\.tgz$/i.test(archivePath)) archivePath = archivePath.replace(/\.tgz$/i, '.tar.gz');

Type guard

function isSupportedArchive(p: string): boolean {
  return /\.(tar\.xz|tar\.gz|zip)$/i.test(p);
}

Try / catch

catch (e) {
  if (e?.code === 'archive_format_unsupported') { /* repackage or rename then retry */ } else throw e;
}

Prevention

When it happens

Trigger: Passing an archive path ending in something other than .tar.xz/.tar.gz/.zip (e.g. .tgz, .tar.bz2, .7z, .tar, no extension, or double extensions like .tar.gz.sig) to inspectNativeArchive/format.

Common situations: Feeding .tgz files (a common gzip-tar alias that is not recognized here); downloading artifacts with mangled names; users supplying .7z/.tar.bz2 archives; CI renaming artifacts to include hashes before the extension.

Related errors


AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27). Data as JSON: /api/errors/ed6dc6e6cb402382. Report an issue: GitHub.