{"record":{"id":"cd93b4234f778b26","repo":"astral-sh/ruff","slug":"flag-reason-cannot-contain-newline-characters","errorCode":null,"errorMessage":"{flag} <reason> cannot contain newline characters","messagePattern":"(.+?) <reason> cannot contain newline characters","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ruff/src/lib.rs","lineNumber":338,"sourceCode":"        warn_user!(\"Detected debug build without --no-cache.\");\n    }\n\n    let suppression = cli\n        .add_noqa\n        .as_ref()\n        .map(|reason| (reason, SuppressionKind::Noqa, \"--add-noqa\"))\n        .or_else(|| {\n            cli.add_ignore\n                .as_ref()\n                .map(|reason| (reason, SuppressionKind::Ignore, \"--add-ignore\"))\n        });\n\n    if let Some((reason, suppression_kind, flag)) = suppression {\n        if !fix_mode.is_generate() {\n            warn_user!(\"--fix is incompatible with {flag}.\");\n        }\n        if reason.contains(['\\n', '\\r']) {\n            return Err(anyhow::anyhow!(\n                \"{flag} <reason> cannot contain newline characters\"\n            ));\n        }\n\n        let reason_opt = (!reason.is_empty()).then_some(reason.as_str());\n\n        let modifications = commands::add_noqa::add_noqa(\n            &files,\n            &pyproject_config,\n            &config_arguments,\n            reason_opt,\n            suppression_kind,\n        )?;\n        if modifications > 0 && config_arguments.log_level >= LogLevel::Default {\n            let s = if modifications == 1 { \"\" } else { \"s\" };\n            let suppression = match suppression_kind {\n                SuppressionKind::Noqa => \"noqa directive\",\n                SuppressionKind::Ignore => \"ignore comment\",","sourceCodeStart":320,"sourceCodeEnd":356,"githubUrl":"https://github.com/astral-sh/ruff/blob/26f38c119cac42e4d320ba08f09224fdec74af2c/crates/ruff/src/lib.rs#L320-L356","documentation":"When `check` runs with a suppression comment flag that takes a reason (e.g. `--per-file-ignores`-style suppression with `--...-reason`), the reason string is embedded into generated suppression comments. A reason containing newlines would break comment formatting, so check rejects it with this error.","triggerScenarios":"Running `ruff check` with a suppression flag such as `--extend-suppress`/`--suppression-reason`-style argument whose value contains `\\n` or `\\r`, and fix mode is not generating the fix (the newline check applies regardless).","commonSituations":"Shell scripts or CI matrices building the reason from multi-line strings, accidental shell quoting that injects a newline, or YAML/env substitution producing multiline values.","solutions":["Replace newlines in the reason with spaces before passing it to the flag.","Collapse multi-line messages with `tr '\\n' ' '` or equivalent in shell scripts.","Check quoting/substitution in CI variables that supply the reason."],"exampleFix":"// before\nruff check --fixable-reason=\"first line\nsecond line\" .\n// after\nREASON=$(echo \"$MSG\" | tr '\\n' ' ')\nruff check --fixable-reason=\"$REASON\" .","handlingStrategy":"validation","validationCode":"REASON=$(printf '%s' \"$REASON\" | tr '\\r\\n' '  ')\ncase \"$REASON\" in *$'\\n'*|*$'\\r'*) echo \"reason must be single-line\"; exit 2;; esac","typeGuard":"fn is_single_line(s: &str) -> bool { !s.contains(['\\n', '\\r']) }","tryCatchPattern":"match run_check(suppression_reason) {\n    Err(e) if e.to_string().ends_with(\"cannot contain newline characters\") => {\n        eprintln!(\"Flatten the reason to a single line before passing it\");\n    }\n    other => other?,\n}","preventionTips":["Sanitize any variable feeding a suppression reason with tr/awk to strip newlines.","Keep reasons short single-line summaries; put details in comments in code instead.","Quote shell variables so command substitution cannot inject multiline output."],"tags":["cli","suppression","arguments","ruff"],"backgroundTag":"newline-in-argument","analyzedSha":"26f38c119cac42e4d320ba08f09224fdec74af2c","analyzedAt":"2026-09-05T10:32:37.492Z","contentChangedAt":"2026-09-05T10:32:37.492Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}