{"record":{"id":"940e91cb838077cc","repo":"astral-sh/ruff","slug":"missing-argument-regex","errorCode":null,"errorMessage":"Missing argument `regex`","messagePattern":"Missing argument `regex`","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ruff_linter/src/rules/flake8_pytest_style/rules/unittest_assert.rs","lineNumber":425,"sourceCode":"                        op: UnaryOp::Not,\n                        operand: Box::new(isinstance),\n                        range: TextRange::default(),\n                        node_index: ruff_python_ast::AtomicNodeIndex::NONE,\n                    };\n                    let expr = node.into();\n                    Ok(assert(&expr, msg))\n                }\n            }\n            UnittestAssert::Regex\n            | UnittestAssert::RegexpMatches\n            | UnittestAssert::NotRegex\n            | UnittestAssert::NotRegexpMatches => {\n                let text = args\n                    .get(\"text\")\n                    .ok_or_else(|| anyhow!(\"Missing argument `text`\"))?;\n                let regex = args\n                    .get(\"regex\")\n                    .ok_or_else(|| anyhow!(\"Missing argument `regex`\"))?;\n                let msg = args.get(\"msg\").copied();\n                let node = ast::ExprName {\n                    id: Name::new_static(\"re\"),\n                    ctx: ExprContext::Load,\n                    range: TextRange::default(),\n                    node_index: ruff_python_ast::AtomicNodeIndex::NONE,\n                };\n                let node1 = ast::ExprAttribute {\n                    value: Box::new(node.into()),\n                    attr: Identifier::new(\"search\".to_string(), TextRange::default()),\n                    ctx: ExprContext::Load,\n                    range: TextRange::default(),\n                    node_index: ruff_python_ast::AtomicNodeIndex::NONE,\n                };\n                let node2 = ast::ExprCall {\n                    func: Box::new(node1.into()),\n                    arguments: Arguments {\n                        args: [(**regex).clone(), (**text).clone()].into(),","sourceCodeStart":407,"sourceCodeEnd":443,"githubUrl":"https://github.com/astral-sh/ruff/blob/15f3fe6b15a5f00172f34b0f542f8ea277f5a586/crates/ruff_linter/src/rules/flake8_pytest_style/rules/unittest_assert.rs#L407-L443","documentation":"Same regex-assert rewrite: after `text`, the pattern argument `regex` is required to build `re.search(regex, text)`. When `args_map` contains no `\"regex\"` entry, `generate_assert` fails with this error instead of emitting the pytest-style fix.","triggerScenarios":"`Regex`-family `generate_assert` where the call supplied `text` but no second positional pattern and no `regex=` keyword — e.g. `self.assertRegex(log_output)`.","commonSituations":"Regex assertions whose pattern was removed or left as a placeholder during test edits; non-unittest `assertRegex` helpers with different arity being auto-fixed by PT009.","solutions":["Provide the pattern: `self.assertRegex(text, r'expected')`.","Exclude PT009 for the file if the method is custom and should not be converted.","When working on Ruff, re-check `args_map`'s positional-name zip for the `['text', 'regex', 'msg']` spec.","Re-run `ruff check --fix` after correcting the call."],"exampleFix":"// before\nself.assertRegex(text)\n// after\nself.assertRegex(text, r'\\d{4}-\\d{2}-\\d{2}')","handlingStrategy":"validation","validationCode":"def valid_regex_assert(call_args, call_kwargs):\n    return (len(call_args) >= 2) or (len(call_args) == 1 and 'regex' in call_kwargs)","typeGuard":"def has_regex(args: tuple, kwargs: dict) -> bool:\n    return len(args) >= 2 or 'regex' in kwargs","tryCatchPattern":null,"preventionTips":["Always pass a pattern as the second argument to assertRegex/assertNotRegex.","Store patterns in named constants so refactorings do not drop them from calls.","Run `ruff check --no-fix` on test directories as a pre-merge gate.","Suppress PT009 for files using custom regex-assert helpers with different arity."],"tags":["linter","rust","pytest-style","argument-missing","regex"],"backgroundTag":"missing-required-argument","analyzedSha":"15f3fe6b15a5f00172f34b0f542f8ea277f5a586","analyzedAt":"2026-09-05T10:32:37.492Z","contentChangedAt":"2026-09-05T10:32:37.492Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}