{"record":{"id":"1f6eb9ee4a0feb32","repo":"sigoden/dufs","slug":"invalid-auth-rule","errorCode":null,"errorMessage":"Invalid auth `{rule}`","messagePattern":"Invalid auth `(.+?)`","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/auth.rs","lineNumber":70,"sourceCode":"    pub fn new(raw_rules: &[&str]) -> Result<Self> {\n        if raw_rules.is_empty() {\n            return Ok(Self::default());\n        }\n        let new_raw_rules = split_rules(raw_rules);\n        let mut use_hashed_password = false;\n        let mut annoy_paths = None;\n        let mut account_paths_pairs = vec![];\n        for rule in &new_raw_rules {\n            let (account, paths) =\n                split_account_paths(rule).ok_or_else(|| anyhow!(\"Invalid auth `{rule}`\"))?;\n            if account.is_empty() {\n                if annoy_paths.is_some() {\n                    bail!(\"Invalid auth, no duplicate anonymous rules\");\n                }\n                annoy_paths = Some(paths)\n            } else if let Some((user, pass)) = account.split_once(':') {\n                if user.is_empty() || pass.is_empty() {\n                    bail!(\"Invalid auth `{rule}`\");\n                }\n                account_paths_pairs.push((user, pass, paths));\n            }\n        }\n        let mut anonymous = None;\n        if let Some(paths) = annoy_paths {\n            let mut access_paths = AccessPaths::default();\n            access_paths\n                .merge(paths)\n                .ok_or_else(|| anyhow!(\"Invalid auth value `@{paths}\"))?;\n            anonymous = Some(access_paths);\n        }\n        let mut users = IndexMap::new();\n        for (user, pass, paths) in account_paths_pairs.into_iter() {\n            let mut access_paths = AccessPaths::default();\n            access_paths\n                .merge(paths)\n                .ok_or_else(|| anyhow!(\"Invalid auth value `{user}:{pass}@{paths}\"))?;","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/sigoden/dufs/blob/fe7fd564f80dfbac361c8e0589c3845638149d38/src/auth.rs#L52-L88","documentation":"Auth::new in src/args.rs (auth.rs) validates each --auth rule of the form user:pass@path. When an account segment contains a colon, it splits into user and pass; if either side is empty the rule is rejected with \"Invalid auth `{rule}`\". This catches rules like ':pass@/' or 'user:@/'.","triggerScenarios":"A rule like --auth \"user:@/data\" (empty password) or \":secret@/data\" (empty user), where split_once(':') succeeds but one half is empty.","commonSituations":"Passwords containing special characters that a shell or config templater stripped; forgetting the password field; password legitimately empty but dufs requires non-empty both parts; colons in passwords splitting incorrectly — note ':' is the user/pass separator, so passwords containing ':' need care.","solutions":["Provide both a non-empty user and a non-empty password in each rule","Quote the --auth value in the shell so special characters aren't stripped","Use a hashed password (sha256) if embedding the plaintext is problematic","Remember ':' separates user and pass — escape/restructure passwords that contain ':'"],"exampleFix":"# before\ndufs --auth \"admin:@/data\"\n# after\ndufs --auth \"admin:secretpw@/data\"","handlingStrategy":"validation","validationCode":"# every rule must be user:pass@path with non-empty user and pass\necho \"$AUTH\" | tr ',;' '\\n' | while IFS= read -r r; do\n  acct=${r%%@*}; user=${acct%%:*}; pass=${acct#*:}\n  [ -n \"$user\" ] && [ -n \"$pass\" ] || { echo \"bad auth rule: $r\"; exit 1; }\ndone","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never leave user or pass empty in a rule","Quote --auth values in the shell","Beware passwords containing ':' — dufs splits on the first colon","Prefer hashed passwords for production"],"tags":["cli","auth","rust","configuration","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"fe7fd564f80dfbac361c8e0589c3845638149d38","analyzedAt":"2026-09-09T13:01:22.843Z","contentChangedAt":"2026-09-09T13:01:22.843Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}