{"record":{"id":"9cc88e5d0164eb0e","repo":"astral-sh/ruff","slug":"arguments-should-be-non-empty","errorCode":null,"errorMessage":"Arguments should be non-empty","messagePattern":"Arguments should be non-empty","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/ruff_linter/src/rules/flake8_comprehensions/fixes.rs","lineNumber":291,"sourceCode":"            value: arg.value.clone(),\n            comma: arg.comma.clone(),\n            whitespace_before_colon: ParenthesizableWhitespace::default(),\n            whitespace_after_colon: ParenthesizableWhitespace::SimpleWhitespace(SimpleWhitespace(\n                \" \",\n            )),\n        })\n        .collect();\n\n    tree = Expression::Dict(Box::new(Dict {\n        elements,\n        lbrace: LeftCurlyBrace {\n            whitespace_after: call.whitespace_before_args.clone(),\n        },\n        rbrace: RightCurlyBrace {\n            whitespace_before: call\n                .args\n                .last()\n                .expect(\"Arguments should be non-empty\")\n                .whitespace_after_arg\n                .clone(),\n        },\n        lpar: vec![],\n        rpar: vec![],\n    }));\n\n    Ok(Edit::range_replacement(\n        pad_expression(\n            tree.codegen_stylist(stylist),\n            expr.range(),\n            checker.locator(),\n            checker.semantic(),\n        ),\n        expr.range(),\n    ))\n}\n","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/astral-sh/ruff/blob/26f38c119cac42e4d320ba08f09224fdec74af2c/crates/ruff_linter/src/rules/flake8_comprehensions/fixes.rs#L273-L309","documentation":"When building the replacement dict literal for C408, the fix copies the whitespace after the last call argument into the closing brace. The diagnostic only fires for non-empty calls, so `call.args.last()` is assumed to exist; if a fix is applied to an empty `dict()`, this expect panics.","triggerScenarios":"Applying the C408 fix to a `dict()` call with zero arguments — a mismatch between the diagnostic condition (which should require arguments) and the fix path.","commonSituations":"Running `ruff --fix` over code containing `dict()` where an empty-args case leaked through detection; version regressions in the flake8-comprehensions rules.","solutions":["Report the crash to Ruff with the minimal input","Upgrade/downgrade to a Ruff version where the empty-call fix is guarded","Suppress C408 for the offending line (`# noqa: C408`) until fixed","Manually replace `dict()` with `{}`"],"exampleFix":"// before\nlet last = call.args.last().expect(\"Arguments should be non-empty\");\n// after\nlet Some(last) = call.args.last() else { return Err(anyhow!(\"C408 fix requires at least one argument\")) };","handlingStrategy":"try-catch","validationCode":"# don't emit/apply C408 fixes for empty calls\nif src_contains_call('dict', ''):\n    print('empty dict() — replace with {} manually instead of --fix')","typeGuard":"def has_args(call_src: str) -> bool:\n    inner = call_src[call_src.index('(')+1:call_src.rindex(')')].strip()\n    return len(inner) > 0","tryCatchPattern":null,"preventionTips":["Preview fixes with `ruff --fix --diff` before applying","Replace `dict()` with `{}` in source; it needs no autofix","Upgrade Ruff when crash reports for C408 fixes are resolved"],"tags":["rust","panic","flake8-comprehensions","autofix","c408"],"backgroundTag":"autofix-invariant-violation","analyzedSha":"26f38c119cac42e4d320ba08f09224fdec74af2c","analyzedAt":"2026-09-05T10:32:37.492Z","contentChangedAt":"2026-09-05T10:32:37.492Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}