oxc-project/oxc · warning

Title must be a string

Error message

Title must be a string

What it means

Diagnostic from the shared jest/vitest `valid-title` rule (title_must_be_string_diagnostic). It fires when the title argument of a `describe`/`test`/`it`/`it.skip`-style block is not a string — a number, identifier, or interpolated template. Non-string titles break reporters and test filtering that assume text titles.

Source

Thrown at crates/oxc_linter/src/rules/shared/jest_vitest/valid_title.rs:24

use oxc_ast::{
    AstKind,
    ast::{Argument, BinaryExpression, Expression},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_span::{GetSpan, Span};
use oxc_str::CompactStr;

use crate::{
    context::LintContext,
    utils::{
        JestFnKind, JestGeneralFnKind, PossibleJestNode, is_string_raw_member_expression,
        parse_general_jest_fn_call,
    },
};

fn title_must_be_string_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Title must be a string")
        .with_help("Replace your title with a string")
        .with_label(span)
}

fn empty_title_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Should not have an empty title")
        .with_help("Write a meaningful title for your test")
        .with_label(span)
}

fn duplicate_prefix_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Should not have duplicate prefix")
        .with_help("The function name already has the prefix, try to remove the duplicate prefix")
        .with_label(span)
}

fn accidental_space_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Should not have leading or trailing spaces")

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Use a string literal: `it('adds numbers', fn)`.
  2. For dynamic titles use a non-interpolated raw template or build a plain string: `it(`case ${name}`, fn)` is flagged when interpolated — prefer a literal or configure accordingly; simplest is a static string or `` it(name, fn) `` only when `name` is a string variable intended as the title and the rule option allows it (default requires literals).
  3. If variable titles are intentional, review valid-title options or disable the rule for those lines.

Example fix

// before
test(42, () => { /* ... */ });

// after
test('returns 42', () => { /* ... */ });
Defensive patterns

Strategy: type-guard

Validate before calling

function assertTitle(title: unknown, fnName: string): string {
  if (typeof title !== 'string' || title.length === 0) {
    throw new TypeError(`${fnName} requires a non-empty string title`);
  }
  return title;
}

Type guard

function isStringTitle(t: unknown): t is string {
  return typeof t === 'string';
}
// usage: test(isStringTitle(t) ? t : fallbackName, fn)

Prevention

When it happens

Trigger: `parse_general_jest_fn_call` resolves the jest call; when the title argument is not a string literal / raw template (is_string_raw_member_expression handles a few raw cases), the diagnostic fires. Examples: `test(123, fn)`, `it(someVariable, fn)`, `describe(`unit-${i}`, fn)` with interpolation.

Common situations: Data-driven tests that accidentally pass the row object/number as title instead of a template string; renaming constants and passing the identifier; migrated suites that stored titles in variables.

Related errors


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