astral-sh/ruff · warning

Expected two arguments

Error message

Expected two arguments

What it means

Raised by the C417/unnecessary-map fix while converting `map(lambda x: ..., iterable)` into a comprehension. When the outer call has a single argument, that argument must itself be a call whose two arguments are the lambda and the iterable; if the inner call's args are not exactly two, the fixer bails.

Source

Thrown at crates/ruff_linter/src/rules/flake8_comprehensions/fixes.rs:680

}

/// (C417) Convert `map(lambda x: x * 2, bar)` to `(x * 2 for x in bar)`.
pub(crate) fn fix_unnecessary_map(
    call_ast_node: &ExprCall,
    parent: Option<&Expr>,
    object_type: ObjectType,
    locator: &Locator,
    stylist: &Stylist,
) -> Result<Edit> {
    let module_text = locator.slice(call_ast_node);
    let mut tree = match_expression(module_text)?;
    let call = match_call_mut(&mut tree)?;

    let (lambda, iter) = match call.args.as_slice() {
        [call] => {
            let call = match_call(&call.value)?;
            let [lambda, iter] = call.args.as_slice() else {
                bail!("Expected two arguments");
            };
            let lambda = match_lambda(&lambda.value)?;
            let iter = &iter.value;
            (lambda, iter)
        }
        [lambda, iter] => {
            let lambda = match_lambda(&lambda.value)?;
            let iter = &iter.value;
            (lambda, iter)
        }
        _ => bail!("Expected a call or lambda"),
    };

    // Format the lambda target.
    let target = match lambda.params.params.as_slice() {
        // Ex) `lambda: x`
        [] => AssignTargetExpression::Name(Box::new(Name {
            value: "_",

View on GitHub (pinned to 26f38c119c)

Solutions

  1. Re-run ruff to refresh diagnostics against current code.
  2. Rewrite the `map`/`lambda` combination as an explicit comprehension by hand.
  3. Add `# noqa: C417` if the lambda signature is intentionally non-trivial and the rule should not apply.

Example fix

// before
squares = map(lambda x: x ** 2, numbers)
// after
squares = (x ** 2 for x in numbers)  # or [x ** 2 for x in numbers]
Defensive patterns

Strategy: validation

Validate before calling

assert len(inner_call.args) == 2, 'map(lambda ..., iter) fix needs exactly two inner args'

Type guard

def is_lambda_plus_iter(args):
    return len(args) == 2 and isinstance(args[0], ast.Lambda)

Try / catch

try:
    apply_autofix(diagnostic)
except Exception:
    write_comprehension_by_hand()

Prevention

When it happens

Trigger: `ruff check --fix` on code like `map(lambda f, *rest: f(*rest), fns)` where the inner call argument list is not exactly `[lambda, iterable]`, or `map(f(...))` whose callee call has extra arguments.

Common situations: Lambdas with default/star args wrapped in other calls; starmap-style patterns; refactored code where an extra argument was inserted between diagnostic generation and fixing.

Related errors


AI-assisted analysis of astral-sh/ruff@26f38c119c (2026-09-05). Data as JSON: /api/errors/7c0763225d3a454b. Report an issue: GitHub.