denoland/deno · error · ParseError

missing index

Error message

missing index '{}'

What it means

On the parsing side of eszip v2, each embedded npm package lists dependencies as indexes into the package table. pkg_index_to_pkg_id maps those indexes to ids; a dependency pointing at an index with no corresponding package yields ParseError::InvalidV2NpmPackage with cause "missing index '<N>'". The archive's npm package table is internally inconsistent — a corrupted or wrongly-generated eszip.

Solutions

  1. Regenerate the eszip/compiled binary from source with a current Deno version
  2. Verify integrity of the artifact in transit (sha256 on both ends) and re-transfer if it differs
  3. If you build tooling on eszip, ensure writer and reader use the same crate version so tables are written consistently
  4. If corruption recurs on clean builds, reduce to a repro and report to denoland

Example fix

# before
deno run ./app.corrupted  # eszip parse: missing index '3'

# after
sha256sum ./app # compare against build-time checksum; rebuild on mismatch
deno compile -o ./app src/mod.ts && deno run ./app
Defensive patterns

Strategy: try-catch

Validate before calling

// eszip consumers: verify integrity before parsing
const bytes = await Deno.readFile(archivePath);
const digest = await crypto.subtle.digest("SHA-256", bytes);
if (expectedSha && toHex(digest) !== expectedSha) throw new Error("eszip integrity check failed");
// then hand `bytes` to the parser

Try / catch

// Rust, when parsing eszip v2
match eszip::EszipV2::parse(bytes) {
    Err(ParseError::InvalidV2NpmPackage(name, e)) if e.to_string().contains("missing index") => {
        // archive is inconsistent: re-encode from source, do not retry parse
        return Err(anyhow!("corrupt eszip: package {name} has dangling index; rebuild required"));
    }
    r => r?,
}

Prevention

When it happens

Trigger: Feeding eszip v2 a truncated or bit-flipped archive where a dependency index exceeds the package count; an eszip written by a buggy/older writer that dropped a package but left references; hand-crafted or patched archives with mismatched tables.

Common situations: Compiled binaries corrupted in transfer (partial upload, interrupted docker build layer); artifacts produced by mismatched deno/eszip crate versions in custom pipelines; checksum-unverified downloads of compile output.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/fa73f6e7f38daca6. Report an issue: GitHub.

Appendix: source

Thrown at libs/eszip/v2.rs:1785

  let mut pkg_index_to_pkg_id = HashMap::with_capacity(packages.len());
  for (i, pkg) in packages.iter().enumerate() {
    let id = NpmPackageId::from_serialized(&pkg.name).map_err(|err| {
      ParseError::InvalidV2NpmPackage(pkg.name.clone(), err.into())
    })?;
    pkg_index_to_pkg_id.insert(EszipNpmPackageIndex(i as u32), id);
  }
  let mut final_packages = Vec::with_capacity(packages.len());
  for (i, pkg) in packages.into_iter().enumerate() {
    let eszip_id = EszipNpmPackageIndex(i as u32);
    let id = pkg_index_to_pkg_id.get(&eszip_id).unwrap();
    let mut dependencies = HashMap::with_capacity(pkg.dependencies.len());
    for (key, pkg_index) in pkg.dependencies {
      let id = match pkg_index_to_pkg_id.get(&pkg_index) {
        Some(id) => id,
        None => {
          return Err(ParseError::InvalidV2NpmPackage(
            pkg.name,
            anyhow::anyhow!("missing index '{}'", pkg_index.0),
          ));
        }
      };
      dependencies.insert(StackString::from_string(key), id.clone());
    }
    final_packages.push(SerializedNpmResolutionSnapshotPackage {
      id: id.clone(),
      system: Default::default(),
      dist: Default::default(),
      dependencies,
      optional_dependencies: Default::default(),
      extra: Default::default(),
      is_deprecated: false,
      has_bin: false,
      has_scripts: false,
      optional_peer_dependencies: Default::default(),
    });
  }

View on GitHub (pinned to 9ad36f7a2c)