{"record":{"id":"4e9e13ee611d71f6","repo":"oxc-project/oxc","slug":"second-argument-must-be-a-function","errorCode":null,"errorMessage":"Second argument must be a function","messagePattern":"Second argument must be a function","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/oxc_linter/src/rules/shared/jest_vitest/valid_describe_callback.rs","lineNumber":18,"sourceCode":"use oxc_ast::{\n    AstKind,\n    ast::{Argument, Expression, FunctionBody, Statement},\n};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_span::{GetSpan, Span};\n\nuse crate::{\n    context::LintContext,\n    utils::{JestFnKind, JestGeneralFnKind, PossibleJestNode, parse_general_jest_fn_call},\n};\n\nfn valid_describe_callback_diagnostic(\n    x1: &'static str,\n    x2: &'static str,\n    span3: Span,\n) -> OxcDiagnostic {\n    OxcDiagnostic::warn(x1).with_help(x2).with_label(span3)\n}\n\n#[derive(Clone, Copy)]\npub struct ValidDescribeCallbackOptions {\n    allow_async_describe_callback: bool,\n    allow_describe_options_argument: bool,\n}\n\nimpl ValidDescribeCallbackOptions {\n    pub const JEST: Self =\n        Self { allow_async_describe_callback: false, allow_describe_options_argument: false };\n\n    pub const VITEST: Self =\n        Self { allow_async_describe_callback: true, allow_describe_options_argument: true };\n}\n\npub fn run<'a>(\n    possible_jest_node: &PossibleJestNode<'a, '_>,","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/shared/jest_vitest/valid_describe_callback.rs#L1-L36","documentation":"Diagnostic from the oxlint `jest/valid-describe-callback` rule (source: crates/oxc_linter/src/rules/shared/jest_vitest/valid_describe_callback.rs:18). This variant ('Second argument must be a function') fires when the describe callback slot is occupied by something that is not a function - an options object, string, or array. The shared builder `valid_describe_callback_diagnostic(x1, x2, span3)` emits the message with a help string.","triggerScenarios":"`describe('title', { timeout: 1000 })`, `describe('title', 'not a function')`, or passing a non-callable second argument. Note the `allow_describe_options_argument` option (Jest preset sets it false) exists in the source - when enabled, an options object as third argument is tolerated.","commonSituations":"Confusing describe with test, which does accept per-test options objects; migrating suites where someone tried to pass jest options to describe; callback variable that is undefined due to an import typo.","solutions":["Make the second argument a function: `describe('title', () => { /* tests */ })`.","If you intended per-call options, describe does not support them (except via the allow-describe-options-argument escape hatch); put timeouts on the test or use `jest.setTimeout`.","Check the callback identifier actually resolves - an undefined import produces this same error."],"exampleFix":"// before\ndescribe('sync', { timeout: 5000 });\n\n// after\ndescribe('sync', () => {\n  test('finishes', () => { /* ... */ }, 5000);\n});","handlingStrategy":"validation","validationCode":"// rg -nU \"describe\\([^)]*,\\s*(\\{|['\\\"]|\\[)\" tests/ -t ts -t js","typeGuard":"// Guard before running a suite built from data (JS):\nfunction isDescribeArgsOk(title, cb) {\n  return typeof title === 'string' && typeof cb === 'function';\n}","tryCatchPattern":null,"preventionTips":["Remember: per-call options belong to test(), not describe()","Verify imported callback symbols resolve (undefined imports land here)"],"tags":["jest","vitest","oxlint","describe","validation"],"backgroundTag":"jest-describe-callback-validation","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}