avajs/ava · error · ChecksumError

Checksum mismatch

Error message

Checksum mismatch

What it means

Every snapshot file stores a SHA-256 hash of its compressed payload. decodeSnapshots() recomputes the hash of the compressed bytes and compares it to the stored bytes; when they differ the file has been modified or corrupted since it was written, so AVA throws ChecksumError rather than decoding tampered data.

Source

Thrown at lib/snapshot-manager.js:260

		throw new VersionMismatchError(snapPath, version);
	}

	const sha256sumOffset = versionOffset + 2;
	const compressedOffset = sha256sumOffset + SHA_256_HASH_LENGTH;
	const compressed = buffer.slice(compressedOffset);

	return {
		version, compressed, sha256sumOffset, compressedOffset,
	};
}

function decodeSnapshots(buffer, snapPath) {
	const {compressed, sha256sumOffset, compressedOffset} = extractCompressedSnapshot(buffer, snapPath);

	const sha256sum = crypto.createHash('sha256').update(compressed).digest();
	const expectedSum = buffer.slice(sha256sumOffset, compressedOffset);
	if (!sha256sum.equals(expectedSum)) {
		throw new ChecksumError(snapPath);
	}

	const decompressed = zlib.gunzipSync(compressed);
	return decodeCbor(decompressed, {
		ignoreGlobalTags: true,
	});
}

class Manager {
	constructor(options) {
		this.dir = options.dir;
		this.recordNewSnapshots = options.recordNewSnapshots;
		this.updating = options.updating;
		this.relFile = options.relFile;
		this.reportFile = options.reportFile;
		this.reportPath = options.reportPath;
		this.snapFile = options.snapFile;
		this.snapPath = options.snapPath;

View on GitHub (pinned to bbfd946322)

Solutions

  1. Regenerate the snapshot: delete the .snap file and run ava --update-snapshots
  2. Restore the original from git (git checkout -- <file>.snap) and ensure no text filters modify it (mark *.snap binary in .gitattributes)
  3. Never merge or hand-edit .snap files; resolve conflicts by regenerating them instead

Example fix

// before (.gitattributes)
*.snap text
// after
*.snap -text
*.snap binary
Defensive patterns

Strategy: validation

Validate before calling

const crypto = require('crypto');
const buf = fs.readFileSync(snapPath);
const nl = buf.indexOf(0x0A);
const versionOffset = nl + 1;
const sha256sumOffset = versionOffset + 2;
const compressedOffset = sha256sumOffset + 32;
const sum = crypto.createHash('sha256').update(buf.slice(compressedOffset)).digest();
if (!sum.equals(buf.slice(sha256sumOffset, compressedOffset))) {
  console.warn(`${snapPath} checksum mismatch — file was modified; regenerate`);
}

Type guard

function checksumOk(buffer, sha256sumOffset, compressedOffset) {
  const crypto = require('crypto');
  return crypto.createHash('sha256').update(buffer.slice(compressedOffset)).digest()
    .equals(buffer.slice(sha256sumOffset, compressedOffset));
}

Try / catch

try {
  decodeSnapshots(buffer, snapPath);
} catch (err) {
  if (/Checksum mismatch/i.test(err.message)) {
    // git checkout -- <file>.snap or regenerate with --update-snapshots
  } else { throw err; }
}

Prevention

When it happens

Trigger: The compressed region of the .snap file was edited after creation (manual edits, patch tools, line-ending conversion altering bytes) or the file was truncated so the stored-hash slice no longer matches the payload.

Common situations: Hand-editing snapshot files to 'fix' tests; git filters or editors that rewrite file bytes; merge conflicts resolved incorrectly in a .snap file; corrupted transfer of snapshot artifacts in CI.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of avajs/ava@bbfd946322 (2026-09-02). Data as JSON: /api/errors/7501c5c2d3adf5d2. Report an issue: GitHub.