oxc-project/oxc · warning

Snapshot hint must be a string literal.

Error message

Snapshot hint must be a string literal.

What it means

This is the oxlint `prefer-snapshot-hint` rule, hint-type branch. The hint argument exists so humans can identify a snapshot in the snapshot file, which only works if it is a string literal; Jest stringifies whatever it receives, so a template expression or identifier passes through opaquely and defeats the purpose. When the single argument to an external snapshot matcher is not a string literal, this diagnostic asks for a literal hint (or property matcher + literal hint).

Source

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

        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).
    #[default]
    Multi,
}

pub const DOCUMENTATION: &str = r"### What it does

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Pass the hint as a string literal: `toMatchSnapshot('login form')`.
  2. When using property matchers, put the object first and the literal hint second: `toMatchSnapshot({ id: expect.any(Number) }, 'user row')`.
  3. Avoid dynamic/hoisted hint expressions — the whole point is a stable, greppable label.

Example fix

// before
expect(result).toMatchSnapshot(hintFromConfig);

// after
expect(result).toMatchSnapshot('migration result');
Defensive patterns

Strategy: validation

Validate before calling

// .oxlintrc.json
{ "rules": { "jest/prefer-snapshot-hint": "error" } }

npx oxlint tests/

Prevention

When it happens

Trigger: A `toMatchSnapshot`/`toThrowErrorMatchingSnapshot` call in a hint-requiring scope whose first argument is not a string literal — e.g. `expect(x).toMatchSnapshot(42)`, `toMatchSnapshot(someVar)`, or a single non-literal argument where a hint was expected.

Common situations: Passing a property-matcher object but forgetting the second hint argument; hoisting hint text into a constant; template literals that are not literals in the AST sense.

Related errors


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