astral-sh/ruff · warning

Cannot offer a fix when there are multiple __all__ definitio

Error message

Cannot offer a fix when there are multiple __all__ definitions

What it means

When a F401 unused import should be re-exported via `__all__`, the fixer can only handle zero or one `__all__` definition in the module. Multiple `__all__` assignments make the target of the edit ambiguous, so Ruff refuses to offer a fix.

Source

Thrown at crates/ruff_linter/src/rules/pyflakes/rules/unused_import.rs:631

    let imports = {
        let mut imports: Vec<&str> = imports
            .into_iter()
            .map(ImportBinding::symbol_stored_in_outer_scope)
            .collect();
        if imports.is_empty() {
            bail!("Expected import bindings");
        }
        imports.sort_unstable();
        imports
    };

    let edits = match dunder_all_exprs {
        [] => fix::edits::make_redundant_alias(imports.into_iter(), statement),
        [dunder_all] => {
            fix::edits::add_to_dunder_all(imports.into_iter(), dunder_all, checker.stylist())
        }
        _ => bail!("Cannot offer a fix when there are multiple __all__ definitions"),
    };

    // Only emit a fix if there are edits.
    let mut tail = edits.into_iter();
    let head = tail.next().ok_or(anyhow!("No edits to make"))?;

    let isolation = Checker::isolation(checker.semantic().parent_statement_id(node_id));
    Ok(Fix::safe_edits(head, tail).isolate(isolation))
}

/// Returns an iterator over bindings to import statements that appear unused.
///
/// The stable behavior is to return those bindings to imports
/// satisfying the following properties:
///
/// - they are not shadowed
/// - they are not `global`, not `nonlocal`, and not explicit exports (i.e. `import foo as foo`)
/// - they have no references, according to the semantic model

View on GitHub (pinned to 26f38c119c)

Solutions

  1. Consolidate the module to a single `__all__ = [...]` definition, then re-run `ruff --fix`
  2. Manually add the unused symbol to one `__all__` list
  3. Suppress F401 for that import with `# noqa: F401`

Example fix

# before
__all__ = ['A']
__all__ += ['B']  # or a second __all__ = [...]
# after
__all__ = ['A', 'B']
Defensive patterns

Strategy: validation

Validate before calling

# Verify a single __all__ before running the re-export fix:
import ast
alls = [n for n in ast.walk(ast.parse(src))
        if isinstance(n, ast.Assign)
        and any(getattr(t, 'id', None) == '__all__' for t in n.targets)]
assert len(alls) <= 1, 'multiple __all__ definitions will block the fix'

Prevention

When it happens

Trigger: `fix_by_reexporting` found two or more `__all__` expression definitions in the same module while attempting to add unused-import symbols to `__all__`.

Common situations: Large `__init__.py` files where `__all__` is defined more than once (e.g. extended conditionally or split across sections), or generated code that redeclares `__all__`.

Related errors


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