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.
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)
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 Expression::Tuple | Expression::List
- Expected each argument to be a tuple of length two
- Expected one argument in outer function call
- Expected at least one argument in outer function call
- Expected Expression::ListComp | Expression:SetComp | Express
AI-assisted analysis of astral-sh/ruff@26f38c119c (2026-09-05).
Data as JSON: /api/errors/e94a35a455902351.
Report an issue: GitHub.