{"record":{"id":"385d1da86fd18471","repo":"denoland/deno","slug":"expected-the-second-argument-to-assertsnapshot-t","errorCode":null,"errorMessage":"Expected the second argument to assertSnapshot() to be an options object or a message string","messagePattern":"Expected the second argument to assertSnapshot\\(\\) to be an options object or a message string","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"cli/js/40_test_snapshot.js","lineNumber":319,"sourceCode":"}\n\nfunction getErrorMessage(message, options) {\n  return typeof options.msg === \"string\" ? options.msg : message;\n}\n\n/**\n * Implementation of `Deno.TestContext.assertSnapshot()`. `tContext` is the\n * test context object the method was called on.\n */\nexport function assertSnapshot(\n  tContext,\n  actual,\n  options = { __proto__: null },\n) {\n  if (typeof options === \"string\") {\n    options = { __proto__: null, msg: options };\n  } else if (typeof options !== \"object\" || options === null) {\n    throw new TypeError(\n      \"Expected the second argument to assertSnapshot() to be an options object or a message string\",\n    );\n  }\n\n  const context = getSnapshotContext(options);\n  const testName = options.name ?? getFullTestName(tContext);\n  const count = (MapPrototypeGet(context.counts, testName) ?? 0) + 1;\n  MapPrototypeSet(context.counts, testName, count);\n  const name = `${testName} ${count}`;\n\n  if (!ArrayPrototypeIncludes(context.updateQueue, name)) {\n    ArrayPrototypePush(context.updateQueue, name);\n  }\n\n  const serializer = options.serializer ?? serialize;\n  const actualSnapshot = serializer(actual);\n  if (typeof actualSnapshot !== \"string\") {\n    throw new TypeError(\"Snapshot serializer must return a string\");","sourceCodeStart":301,"sourceCodeEnd":337,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/cli/js/40_test_snapshot.js#L301-L337","documentation":"Deno.TestContext.assertSnapshot(actual, options?) accepts as its second user-visible argument either an options object ({ name, msg, serializer, dir, path }) or, as a legacy convenience, a plain message string (cli/js/40_test_snapshot.js). Anything else — a number, boolean, null, or a function — throws this TypeError at call time. The message says \"second argument\" because the test context is the method receiver, so from the caller's seat the options are the second argument after `actual`.","triggerScenarios":"Calling `await t.assertSnapshot(value, 5)`, `t.assertSnapshot(value, null)`, or passing a serializer function directly (`t.assertSnapshot(value, mySerializer)`) instead of an options object (`{ serializer: mySerializer }`).","commonSituations":"Refactoring from std/testing snapshot APIs with different signatures; passing a message that ends up non-string (e.g. a template variable); passing null explicitly as 'no options'.","solutions":["Pass an options object: `await t.assertSnapshot(value, { name: \"render\" })`.","Or pass a message string: `await t.assertSnapshot(value, \"renders correctly\")`.","Wrap custom serializers: `t.assertSnapshot(value, { serializer: mySerializer })`, not `t.assertSnapshot(value, mySerializer)`.","Omit the argument entirely if no options are needed."],"exampleFix":"// before\nawait t.assertSnapshot(result, 5);\nawait t.assertSnapshot(result, mySerializer);\n\n// after\nawait t.assertSnapshot(result, { name: \"result\" });\nawait t.assertSnapshot(result, { serializer: mySerializer });","handlingStrategy":"type-guard","validationCode":"if (typeof opts !== \"undefined\" && !isValidSnapshotOptions(opts)) {\n  throw new Error(\"assertSnapshot options must be an object or a message string\");\n}\nawait t.assertSnapshot(value, opts);","typeGuard":"/** @param {unknown} o @returns {o is string | Record<string, unknown>} */\nfunction isValidSnapshotOptions(o) {\n  return typeof o === \"string\" || (typeof o === \"object\" && o !== null);\n}","tryCatchPattern":null,"preventionTips":["Pass either an options object or a plain string — nothing else; omit the argument when unused.","Wrap custom serializers inside { serializer: fn } rather than passing the function itself.","Do not pass null to mean 'no options'; leave the argument out instead."],"tags":["deno","deno-test","snapshot","assertion","typeerror","api-misuse"],"backgroundTag":"invalid-argument-value","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}