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
- Use a string literal: `it('adds numbers', fn)`.
- 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).
- 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
- Always type test titles as literals; if dynamic, build a string first and assert `typeof title === 'string'` in helpers.
- Enable valid-title in CI so non-string titles fail fast.
- Avoid interpolating counters into template titles unless your convention allows it.
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
- Should not have an empty title
- Should not have duplicate prefix
- Should not have leading or trailing spaces
- {word} is not allowed in test title
- {un_prefixed_name} should match {raw_pattern}
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/45453b6ad49b75f9.
Report an issue: GitHub.