oxc-project/oxc · warning

Snapshot is missing a hint.

Error message

Snapshot is missing a hint.

What it means

This is the oxlint `prefer-snapshot-hint` rule, missing-hint branch. External snapshot matchers (`toMatchSnapshot`, `toThrowErrorMatchingSnapshot`) key their stored snapshots by auto-incrementing numbers within a test; adding or reordering assertions silently shifts those numbers and pollutes reviews. The rule groups snapshot calls per enclosing function scope (including helper functions called from tests) and requires a hint string whenever the mode says one is needed.

Source

Thrown at crates/oxc_linter/src/rules/shared/jest_vitest/prefer_snapshot_hint.rs:28

use oxc_semantic::NodeId;
use oxc_span::Span;

use crate::{
    context::LintContext,
    utils::{
        JestFnKind, JestGeneralFnKind, PossibleJestNode, collect_possible_jest_call_node,
        parse_expect_jest_fn_call,
    },
};

fn snapshot_matcher_too_many_arguments_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("`toMatchSnapshot` takes at most two arguments.")
        .with_help("Pass a hint string, or a property matcher object followed by a hint string.")
        .with_label(span)
}

fn snapshot_missing_hint_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Snapshot is missing a hint.")
        .with_help("Include a hint string to identify this snapshot in the snapshot file.")
        .with_label(span)
}

fn snapshot_hint_must_be_string_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Snapshot hint must be a string literal.")
        .with_help(
            "Provide a string literal as the hint, or pass a property matcher object as the first argument and the hint string as the second.",
        )
        .with_label(span)
}

#[derive(Debug, Clone, Copy, Eq, PartialEq, Deserialize, JsonSchema, Default)]
#[serde(rename_all = "lowercase")]
pub enum SnapshotHintMode {
    /// Require a hint to always be provided when using external snapshot matchers.
    Always,
    /// Require a hint to be provided when there are multiple external snapshot matchers within the scope (meaning it includes nested calls).

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Add a stable hint: `expect(stdout).toMatchSnapshot({}, 'cli --version stdout')` or `toMatchSnapshot('renders header')`.
  2. Convert one-off snapshots to `toMatchInlineSnapshot()` which is exempt.
  3. If hints are unwanted team-wide, set the rule off; if you only disagree with the default, switch mode between 'always' and 'multi' in .oxlintrc.json.

Example fix

// before
const snapshotOutput = ({ stdout, stderr }) => {
  expect(stdout).toMatchSnapshot();
  expect(stderr).toMatchSnapshot();
};

// after
const snapshotOutput = ({ stdout, stderr }, hints) => {
  expect(stdout).toMatchSnapshot({}, `stdout: ${hints.stdout}`);
  expect(stderr).toMatchSnapshot({}, `stderr: ${hints.stderr}`);
};
Defensive patterns

Strategy: validation

Validate before calling

// .oxlintrc.json
{ "rules": { "jest/prefer-snapshot-hint": ["error", "always"] } }

npx oxlint tests/

Prevention

When it happens

Trigger: In mode `always`: any zero-argument `toMatchSnapshot()`/`toThrowErrorMatchingSnapshot()`. In default mode `multi`: zero-argument external snapshot matchers when the same scope (test callback or helper function, nested included) contains 2+ of them. Note `toMatchInlineSnapshot` never triggers this.

Common situations: Helper functions shared by multiple tests that each call toMatchSnapshot (the classic trap: every caller adds snapshots to one scope, numbers shift); growing a test from one to two snapshots without adding hints; CI snapshot diffs full of renumbered entries after inserting an early assertion.

Related errors


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/999527c207416e02. Report an issue: GitHub.