denoland/deno · error · TypeError
Expected the second argument to assertSnapshot() to be an op
Error message
Expected the second argument to assertSnapshot() to be an options object or a message string
What it means
Thrown by assertSnapshot() (cli/js/40_test_snapshot.js), the implementation behind t.assertSnapshot() in Deno tests. Besides the value under test, the call accepts either an options object ({ name, serializer, msg, ... }) or a plain string used as the failure message. Anything else as that argument is a TypeError.
Source
Thrown at cli/js/40_test_snapshot.js:319
}
function getErrorMessage(message, options) {
return typeof options.msg === "string" ? options.msg : message;
}
/**
* Implementation of `Deno.TestContext.assertSnapshot()`. `tContext` is the
* test context object the method was called on.
*/
export function assertSnapshot(
tContext,
actual,
options = { __proto__: null },
) {
if (typeof options === "string") {
options = { __proto__: null, msg: options };
} else if (typeof options !== "object" || options === null) {
throw new TypeError(
"Expected the second argument to assertSnapshot() to be an options object or a message string",
);
}
const context = getSnapshotContext(options);
const testName = options.name ?? getFullTestName(tContext);
const count = (MapPrototypeGet(context.counts, testName) ?? 0) + 1;
MapPrototypeSet(context.counts, testName, count);
const name = `${testName} ${count}`;
if (!ArrayPrototypeIncludes(context.updateQueue, name)) {
ArrayPrototypePush(context.updateQueue, name);
}
const serializer = options.serializer ?? serialize;
const actualSnapshot = serializer(actual);
if (typeof actualSnapshot !== "string") {
throw new TypeError("Snapshot serializer must return a string");View on GitHub (pinned to 89f33cbef2)
Solutions
- Pass an options object: t.assertSnapshot(value, { msg: "context" }) or t.assertSnapshot(value, { name: "my snapshot", serializer })
- Or pass the message directly as a string: t.assertSnapshot(value, "my message")
- If options come from a variable, default it: opts ?? {}
Example fix
// before
await t.assertSnapshot(result, true);
// after
await t.assertSnapshot(result, { msg: "rendered output" }); Defensive patterns
Strategy: type-guard
Validate before calling
function normalizeSnapshotOptions(arg) {
if (typeof arg === "string") return { msg: arg };
if (typeof arg === "object" && arg !== null) return arg;
return {}; // or throw your own clearer error before calling the API
} Type guard
/** @param {unknown} arg */
function isSnapshotOptionsOrMessage(arg) {
return typeof arg === "string" ||
(typeof arg === "object" && arg !== null);
} Prevention
- Always pass an options object literal at call sites — never a coerced truthy value
- Default optional third args with `?? {}` when threading options through helpers
When it happens
Trigger: Calling t.assertSnapshot(value, opts) where opts is a boolean, number, symbol, or a non-object non-string — e.g. passing a message as a template-literal coercion attempt (true), passing options through a variable that is undefined-adjacent (e.g. a misnamed flag), or passing an array where the string|object union is expected (arrays pass the object check and are treated as an options object).
Common situations: Refactoring from assertEquals(value, expected, "msg") and passing a non-string third-arg habit into assertSnapshot; building options conditionally and letting a falsy sentinel (false/0) leak through; API drift from other snapshot libs whose signature is (value, nameStringOrObject).
Related errors
- Snapshot serializer must return a string
- Missing snapshot file.
- Missing snapshot: ${name}
- Snapshot does not match: [Diff] Actual / Expected ${di
- invalid doc test hashbang: #!/bin/sh (binary basename needs
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/385d1da86fd18471.
Report an issue: GitHub.