astral-sh/ruff · error
Missing argument `first`
Error message
Missing argument `first`
What it means
Ruff's flake8-pytest-style rewrite of unittest asserts (PT009, `generate_assert`) converts `self.assertLess`/`assertLessEqual`/`assertIs`/`assertIsNot` calls into plain `assert first <op> second` expressions. It first builds a map from argument names to expressions (`args_map`), then looks up `first`. If the call provides no first argument (positionally or by keyword), the rewrite cannot build the replacement and aborts with this error.
Source
Thrown at crates/ruff_linter/src/rules/flake8_pytest_style/rules/unittest_assert.rs:321
assert(expr, msg)
},
)
}
UnittestAssert::Equal
| UnittestAssert::Equals
| UnittestAssert::FailUnlessEqual
| UnittestAssert::NotEqual
| UnittestAssert::NotEquals
| UnittestAssert::FailIfEqual
| UnittestAssert::Greater
| UnittestAssert::GreaterEqual
| UnittestAssert::Less
| UnittestAssert::LessEqual
| UnittestAssert::Is
| UnittestAssert::IsNot => {
let first = args
.get("first")
.ok_or_else(|| anyhow!("Missing argument `first`"))?;
let second = args
.get("second")
.ok_or_else(|| anyhow!("Missing argument `second`"))?;
let msg = args.get("msg").copied();
let cmp_op = match self {
UnittestAssert::Equal
| UnittestAssert::Equals
| UnittestAssert::FailUnlessEqual => CmpOp::Eq,
UnittestAssert::NotEqual
| UnittestAssert::NotEquals
| UnittestAssert::FailIfEqual => CmpOp::NotEq,
UnittestAssert::Greater => CmpOp::Gt,
UnittestAssert::GreaterEqual => CmpOp::GtE,
UnittestAssert::Less => CmpOp::Lt,
UnittestAssert::LessEqual => CmpOp::LtE,
UnittestAssert::Is => CmpOp::Is,
UnittestAssert::IsNot => CmpOp::IsNot,
_ => unreachable!(),View on GitHub (pinned to 15f3fe6b15)
Solutions
- Fix the flagged call so it passes two arguments: `self.assertLess(a, b)`.
- Confirm the matched method is genuinely a unittest assert; suppress PT009 for files with custom same-named helpers.
- If editing Ruff itself, check that `args_map` zipped `arg_spec` names with positional args correctly.
- Re-run `ruff check --fix` after correcting the test call.
Example fix
// before
def test(self):
self.assertLess()
// after
def test(self):
self.assertLess(actual, expected) Defensive patterns
Strategy: validation
Validate before calling
import inspect
def has_two_operands(obj, name):
method = getattr(obj, name, None)
if not callable(method):
return False
required = [p for p in inspect.signature(method).parameters.values() if p.default is inspect.Parameter.empty]
return len(required) >= 2
assert has_two_operands(self, 'assertLess'), 'assertLess needs (first, second)' Type guard
def has_first_operand(args: tuple, kwargs: dict) -> bool:
return len(args) >= 1 or 'first' in kwargs Prevention
- Always pass both comparands to assertLess/assertLessEqual/assertIs/assertIsNot.
- Run `ruff check` (no --fix) in CI before autofix so incomplete calls surface first.
- Keep test methods on real `unittest.TestCase` classes so signatures match PT009 expectations.
- Avoid dynamically rebinding self.assertX to custom callables with different arities.
When it happens
Trigger: `UnittestAssert::Less/LessEqual/Is/IsNot.generate_assert(args, keywords)` where the mapped args contain no `"first"` entry — e.g. a source call `self.assertLess()` with zero args, or fewer positional args than the arg_spec (`first`, `second`, `msg`).
Common situations: Running `ruff --fix` on test code calling `assertLess`/`assertIs` etc. with an incomplete argument list; dynamically bound methods matching the assert name but not unittest's signature; in-progress edits to test files.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Missing argument `second`
- Missing argument `member`
- Missing argument `container`
- Missing argument `obj`
- Missing argument `cls`
AI-assisted analysis of astral-sh/ruff@15f3fe6b15 (2026-09-05).
Data as JSON: /api/errors/6dbdfe24c5d1b812.
Report an issue: GitHub.