astral-sh/ruff · error
Missing argument `second`
Error message
Missing argument `second`
What it means
Same PT009 assert-rewrite path, but for the `second` operand: `assertLess`/`assertLessEqual`/`assertIs`/`assertIsNot` require two comparands to emit `assert first <op> second`. When `args_map` has no `"second"` entry, `generate_assert` returns this error and no fix is produced.
Source
Thrown at crates/ruff_linter/src/rules/flake8_pytest_style/rules/unittest_assert.rs:324
}
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!(),
};
let expr = compare(first, cmp_op, second);
Ok(assert(&expr, msg))View on GitHub (pinned to 15f3fe6b15)
Solutions
- Complete the call in the flagged test: `self.assertIs(result, None)`.
- Suppress PT009 (ignore rule or per-file-ignores) if the call is not a real unittest method.
- If developing Ruff, audit `args_map`'s positional zip and the keyword fill-in for off-by-one shifts.
- Re-run the fixer after the test call is corrected.
Example fix
// before self.assertIs(value) // after self.assertIs(value, expected)
Defensive patterns
Strategy: validation
Validate before calling
import inspect sig = inspect.signature(self.assertIs) required = [p for p in sig.parameters.values() if p.default is inspect.Parameter.empty] assert len(required) >= 2, 'assertIs requires first and second'
Type guard
def has_second_operand(args: tuple, kwargs: dict) -> bool:
return len(args) >= 2 or ('second' in kwargs and len(args) >= 1) Prevention
- Never call assertIs/assertLess with a single operand; the rewrite requires both.
- Run lint without --fix first to catch incomplete asserts before autofixing.
- Review test diffs after removing an expected value — leftover one-arg asserts trigger this.
- Do not shadow unittest assert names with helpers of different arity.
When it happens
Trigger: `generate_assert` for Less/LessEqual/Is/IsNot where the call supplied `first` (or nothing) but no `second`: e.g. `self.assertIs(x)` with one positional arg and no `second=` keyword.
Common situations: Truncated or hand-edited test calls; non-unittest classes defining `assertIs` with different arity being pattern-matched by PT009; running `--fix` on partially refactored test suites.
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 `first`
- 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/be1a4d92ca0a426b.
Report an issue: GitHub.