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

  1. If the new output is intended, run `deno test --update-snapshots`, inspect the snapshot diff in review, and commit
  2. If the change is unintended, fix the code that produced it — the embedded diff shows exactly what moved
  3. 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

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


AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16). Data as JSON: /api/errors/cb5a310a4fa1abb5. Report an issue: GitHub.