{"record":{"id":"45aa8d8a25ad0292","repo":"sigoden/dufs","slug":"invalid-auth-value-user-pass-paths","errorCode":null,"errorMessage":"Invalid auth value `{user}:{pass}@{paths}","messagePattern":"Invalid auth value `(.+?):(.+?)@(.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/auth.rs","lineNumber":88,"sourceCode":"                    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}\"))?;\n            if let Some(anon_ap) = &anonymous {\n                let orig_user = access_paths.clone();\n                access_paths.absorb_anon(\n                    anon_ap,\n                    &orig_user,\n                    AccessPerm::IndexOnly,\n                    AccessPerm::IndexOnly,\n                );\n            }\n            if pass.starts_with(\"$6$\") {\n                use_hashed_password = true;\n            }\n            users.insert(user.to_string(), (pass.to_string(), access_paths));\n        }\n\n        Ok(Self {\n            empty: false,\n            use_hashed_password,","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/sigoden/dufs/blob/fe7fd564f80dfbac361c8e0589c3845638149d38/src/auth.rs#L70-L106","documentation":"`Auth::new` parses `user:pass@paths` auth entries and merges the paths portion via `AccessPaths::merge`. When that merge fails (unparseable path rules), construction aborts and the full offending `user:pass@paths` value is echoed so the bad part can be located. This prevents starting with silently-wrong per-user permissions.","triggerScenarios":"Any `--auth user:pass@<paths>` value whose `<paths>` section cannot be parsed by `AccessPaths::merge` (empty paths, unknown rule characters, malformed `path:perm` entries).","commonSituations":"Copy-pasting auth strings with stray whitespace or smart quotes; forgetting the path part after `@`; using permission letters other than r/w; shell glob expansion altering the value.","solutions":["Verify the section after `@` is a valid path spec such as `/:rw` or `/:` (read-only default).","Quote the entire `--auth` argument in the shell.","Check the `AccessPaths::merge` implementation for exactly which strings are accepted.","Split complicated multi-path rules across separate `--auth` flags."],"exampleFix":"// before\n--auth admin:secret@:w   (invalid perm/path spec)\n// after\n--auth admin:secret@/:rw","handlingStrategy":"validation","validationCode":"fn check_auth_entry(entry: &str) -> Result<(), String> {\n    let (creds, paths) = entry.split_once('@').ok_or(\"missing @paths\")?;\n    if creds.is_empty() || !creds.contains(':') || paths.is_empty() { return Err(format!(\"bad entry {}\", entry)); }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always include a path section after @ (e.g. @/:rw)","Escape/quote credentials containing special characters","Validate auth entries in startup scripts before launch","Use one --auth flag per user for clarity"],"tags":["rust","authentication","config-validation","cli"],"backgroundTag":"invalid-config-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"}