astral-sh/ruff · warning
Expected container to use a key as the first element
Error message
Expected container to use a key as the first element
What it means
Third check in the same C417 dict-comprehension fix: the first element of the lambda body's pair container must be a simple (starless, unpackless) expression to serve as the key. Starred elements, slices with unusual nodes, etc. cannot become dict keys in the generated comprehension, so the fixer bails.
Solutions
- Replace the starred element with an explicit expression (e.g. `x[0]`) so the fix can apply.
- Rewrite as a manual dict comprehension: `{k: v for ...}` including whatever unpacking you need.
- Add `# noqa: C417` if starred/unpacked keys are intentional.
Example fix
// before
d = dict(map(lambda x: (*x[:2],), rows))
// after
d = {x[0]: x[1] for x in rows} Defensive patterns
Strategy: type-guard
Validate before calling
ok = not isinstance(lam.body.elts[0], ast.Starred)
Type guard
def simple_key(body):
return (isinstance(body, (ast.Tuple, ast.List)) and len(body.elts) == 2
and not isinstance(body.elts[0], ast.Starred)
and not isinstance(body.elts[1], ast.Starred)) Try / catch
try:
apply_autofix(diagnostic)
except Exception:
rewrite_with_explicit_indexing() Prevention
- Avoid starred expressions in key/value tuple bodies
- Use explicit indexing x[0], x[1] for dict-conversion lambdas
- Suppress C417 when unpacking is intentional
When it happens
Trigger: `ruff check --fix` on `dict(map(lambda x: (*x, y), items))` or bodies whose first element is a starred expression like `lambda k: (*a, b)`.
Common situations: Unpacking-heavy lambda bodies from data-processing code; refactors introducing starred args into tuple bodies; stale diagnostics after edits.
Related errors
- Expected a call or lambda
- Expected at least one argument in outer function call
- Expected container to include two elements
- Expected each argument to be a tuple of length two
- Expected Expression::ListComp | Expression:SetComp |…
AI-assisted analysis of astral-sh/ruff@26f38c119c (2026-09-05).
Data as JSON: /api/errors/e94a35a455902351.
Report an issue: GitHub.
Appendix: source
Thrown at crates/ruff_linter/src/rules/flake8_comprehensions/fixes.rs:785
lpar: vec![],
rpar: vec![],
lbrace: LeftCurlyBrace::default(),
rbrace: RightCurlyBrace::default(),
}));
}
ObjectType::Dict => {
let elements = match lambda.body.as_ref() {
Expression::Tuple(tuple) => &tuple.elements,
Expression::List(list) => &list.elements,
_ => {
bail!("Expected tuple or list for dictionary comprehension")
}
};
let [key, value] = elements.as_slice() else {
bail!("Expected container to include two elements");
};
let Element::Simple { value: key, .. } = key else {
bail!("Expected container to use a key as the first element");
};
let Element::Simple { value, .. } = value else {
bail!("Expected container to use a value as the second element");
};
tree = Expression::DictComp(Box::new(DictComp {
for_in: compfor,
lpar: vec![],
rpar: vec![],
key: Box::new(key.clone()),
value: Box::new(value.clone()),
lbrace: LeftCurlyBrace::default(),
rbrace: RightCurlyBrace::default(),
whitespace_before_colon: ParenthesizableWhitespace::default(),
whitespace_after_colon: ParenthesizableWhitespace::SimpleWhitespace(
SimpleWhitespace(" "),
),
}));View on GitHub (pinned to 26f38c119c)