{"record":{"id":"27220eea1d503071","repo":"astral-sh/ruff","slug":"invalidutf8-27220e","errorCode":"InvalidUtf8","errorMessage":"invalid UTF-8 was detected in one or more arguments","messagePattern":"invalid UTF-8 was detected in one or more arguments","errorType":"validation","errorClass":"clap::Error","httpStatus":null,"severity":"error","filePath":"crates/ruff_linter/src/rule_selector.rs","lineNumber":529,"sourceCode":"        type Parser = UnresolvedRuleSelectorParser;\n\n        fn value_parser() -> Self::Parser {\n            UnresolvedRuleSelectorParser\n        }\n    }\n\n    impl TypedValueParser for UnresolvedRuleSelectorParser {\n        type Value = UnresolvedRuleSelector;\n\n        fn parse_ref(\n            &self,\n            _cmd: &clap::Command,\n            _arg: Option<&clap::Arg>,\n            value: &std::ffi::OsStr,\n        ) -> Result<Self::Value, clap::Error> {\n            let value = value\n                .to_str()\n                .ok_or_else(|| clap::Error::new(clap::error::ErrorKind::InvalidUtf8))?;\n\n            Ok(UnresolvedRuleSelector::cli(value))\n        }\n\n        fn possible_values(&self) -> Option<Box<dyn Iterator<Item = PossibleValue> + '_>> {\n            Some(Box::new(\n                std::iter::once(PossibleValue::new(\"ALL\").help(\"all rules\")).chain(\n                    Linter::iter()\n                        .filter_map(|l| {\n                            let prefix = l.common_prefix();\n                            (!prefix.is_empty()).then(|| PossibleValue::new(prefix).help(l.name()))\n                        })\n                        .chain(RuleCodePrefix::iter().filter_map(|prefix| {\n                            // Ex) `UP`\n                            if prefix.short_code().is_empty() {\n                                let code = prefix.linter().common_prefix();\n                                let name = prefix.linter().name();\n                                return Some(PossibleValue::new(code).help(name));","sourceCodeStart":511,"sourceCodeEnd":547,"githubUrl":"https://github.com/astral-sh/ruff/blob/d1087a4b9e03d253a88703f34e0869ee4b805456/crates/ruff_linter/src/rule_selector.rs#L511-L547","documentation":"Rule-selector CLI options (--select, --ignore, --fixable, --unfixable and their --extend-* variants) use UnresolvedRuleSelectorParser, which converts the OsStr argument to str before parsing rule codes. Non-UTF-8 bytes fail the conversion and clap reports ErrorKind::InvalidUtf8.","triggerScenarios":"`ruff check --select <non-UTF-8 bytes>` — a rule-code argument mangled by a legacy-locale shell or produced by a script emitting raw bytes.","commonSituations":"Locale mismatches in terminals or CI; scripts that build argv from byte-oriented sources; extremely rare interactively.","solutions":["Re-run with a UTF-8 locale (`export LANG=C.UTF-8`).","Fix the calling script to emit UTF-8 rule codes.","Verify each code is a real rule name (`ruff rule` lists them)."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"#!/bin/sh\nfor sel in \"$@\"; do\n  printf '%s' \"$sel\" | iconv -f UTF-8 -t UTF-8 >/dev/null 2>&1 || { echo \"selector not UTF-8: $sel\" >&2; exit 1; }\ndone\nexec ruff check --select \"$1\" .","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run terminals and CI in a UTF-8 locale.","Build --select/--ignore lists from typed strings, never raw byte sources."],"tags":["ruff","cli","utf-8","rule-selection","args"],"backgroundTag":"cli-invalid-utf8","analyzedSha":"d1087a4b9e03d253a88703f34e0869ee4b805456","analyzedAt":"2026-08-20T16:33:49.445Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}