denoland/deno · error · AssertionError
Snapshot does not match: [Diff] Actual / Expected ${di
Error message
Snapshot does not match:
[Diff] Actual / Expected
${diff}
To update snapshots, run
deno test --update-snapshots [files]...
What it means
AssertionError from assertSnapshot() (cli/js/40_test_snapshot.js): the serialized actual value differs from the stored expected string for that key. The message embeds a [Diff] Actual / Expected block and tells you the recovery command: `deno test --update-snapshots`. This is the intended failure mode of snapshot testing — the diff is the review artifact.
Source
Thrown at cli/js/40_test_snapshot.js:365
}
}
return;
}
if (!context.fileExists) {
throw new AssertionError(
getErrorMessage("Missing snapshot file.", options),
);
}
if (expectedSnapshot === undefined) {
throw new AssertionError(
getErrorMessage(`Missing snapshot: ${name}`, options),
);
}
if (actualSnapshot === expectedSnapshot) {
return;
}
throw new AssertionError(
getErrorMessage(
getSnapshotNotMatchMessage(actualSnapshot, expectedSnapshot),
options,
),
);
}
function buildSnapshotFileContent(names, getValue) {
const buf = ["export const snapshot = {};"];
for (const name of new SafeArrayIterator(names)) {
const value = getValue(name);
if (value === undefined) {
continue;
}
let formatted = escapeStringForJs(value);
formatted = StringPrototypeIncludes(formatted, "\n")
? `\n${formatted}\n`
: formatted;View on GitHub (pinned to 89f33cbef2)
Solutions
- If the new output is intended, run `deno test --update-snapshots`, inspect the snapshot diff in review, and commit
- If the change is unintended, fix the code that produced it — the embedded diff shows exactly what moved
- Stabilize flaky inputs before re-recording: normalize paths, freeze time, sort collections, mask randomness in the serializer
Example fix
# before deno test # Snapshot does not match: [Diff] Actual / Expected ... # after (intended change) deno test --update-snapshots git diff -- '**/__snapshot__/**' # review, then commit
Defensive patterns
Strategy: try-catch
Validate before calling
// scrub nondeterminism before it reaches the snapshot
const stable = (s) => s.replaceAll(Deno.cwd(), "<cwd>").replace(/\d{4}-\d{2}-\d{2}T[^\s"]+/g, "<ts>");
await t.assertSnapshot(value, { serializer: (v) => stable(String(v)) }); Try / catch
import { AssertionError } from "jsr:@std/assert";
try {
await t.assertSnapshot(value);
} catch (err) {
if (err instanceof AssertionError && err.message.includes("Snapshot does not match")) {
// surface the embedded diff for custom reporting, then decide: fix code or update
throw err;
}
throw err;
} Prevention
- Treat snapshot diffs as review artifacts: regenerate with --update-snapshots only after confirming the change is intended
- Normalize environment-dependent values (paths, timestamps, randomness, map order) in the serializer so snapshots are deterministic
- Review the __snapshot__ diff in every PR that touches output-producing code
When it happens
Trigger: Any change in the snapshotted output: a code change that alters formatting/serialization, dependency upgrades changing error messages or ordering, environment-dependent values (paths, timestamps, random ids) leaking into snapshots, or unordered collections serializing in different orders across runs.
Common situations: Intentional output changes during development needing a snapshot refresh; flaky snapshots caused by absolute paths or map iteration order; a dependency bump changing stack traces or default formatting; platform line-ending differences (CRLF vs LF).
Related errors
- Missing snapshot file.
- Missing snapshot: ${name}
- Expected the second argument to assertSnapshot() to be an op
- Snapshot serializer must return a string
- invalid doc test hashbang: #!/bin/sh (binary basename needs
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/cb5a310a4fa1abb5.
Report an issue: GitHub.