{"record":{"id":"321c9e3a4fb60872","repo":"elkowar/eww","slug":"please-provide-the-path-to-the-config-directory-n","errorCode":null,"errorMessage":"Please provide the path to the config directory, not a file within it","messagePattern":"Please provide the path to the config directory, not a file within it","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/eww/src/paths.rs","lineNumber":22,"sourceCode":"    path::{Path, PathBuf},\n};\n\nuse anyhow::{bail, Result};\n\n/// Stores references to all the paths relevant to eww, and abstracts access to these files and directories\n#[derive(Debug, Clone)]\npub struct EwwPaths {\n    pub log_file: PathBuf,\n    pub log_dir: PathBuf,\n    pub ipc_socket_file: PathBuf,\n    pub config_dir: PathBuf,\n}\n\nimpl EwwPaths {\n    pub fn from_config_dir<P: AsRef<Path>>(config_dir: P) -> Result<Self> {\n        let config_dir = config_dir.as_ref();\n        if config_dir.is_file() {\n            bail!(\"Please provide the path to the config directory, not a file within it\")\n        }\n\n        if !config_dir.exists() {\n            bail!(\"Configuration directory {} does not exist\", config_dir.display());\n        }\n\n        let config_dir = config_dir.canonicalize()?;\n\n        let mut hasher = DefaultHasher::new();\n        format!(\"{}\", config_dir.display()).hash(&mut hasher);\n        // daemon_id is a hash of the config dir path to ensure that, given a normal XDG_RUNTIME_DIR,\n        // the absolute path to the socket stays under the 108 bytes limit. (see #387, man 7 unix)\n        let daemon_id = format!(\"{:x}\", hasher.finish());\n\n        let ipc_socket_file = std::env::var(\"XDG_RUNTIME_DIR\")\n            .map(std::path::PathBuf::from)\n            .unwrap_or_else(|_| std::path::PathBuf::from(\"/tmp\"))\n            .join(format!(\"eww-server_{}\", daemon_id));","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/elkowar/eww/blob/48f5aa8b379adf29da0b0bb9ca04164f65d8bdaa/crates/eww/src/paths.rs#L4-L40","documentation":"EwwPaths::from_config_dir builds the path database for a config directory. If the user passes a file path (e.g. the eww.yuck file itself) instead of the directory containing it, eww rejects it immediately with this message.","triggerScenarios":"Calling EwwPaths::from_config_dir with a path where config_dir.is_file() is true — e.g. `eww --config ~/.config/eww/eww.yuck ...` instead of passing the directory.","commonSituations":"Users point --config at the yuck file instead of its directory; scripts or wrappers pass $0 or a found file path rather than a directory; docs examples copy-pasted incorrectly.","solutions":["Pass the config directory, not a file: `eww --config ~/.config/eww open bar`","Strip the filename from the path in any wrapper script (`dirname \"$path\"`)","Check existing shell aliases/scripts that hardcode the eww.yuck path"],"exampleFix":"// before\neww --config ~/.config/eww/eww.yuck open bar\n// after\neww --config ~/.config/eww open bar","handlingStrategy":"validation","validationCode":"const fs = require('fs');\nif (fs.statSync(configPath).isFile()) throw new Error('Pass the config DIRECTORY, not a file');","typeGuard":"function isDirectory(p) { try { return fs.statSync(p).isDirectory(); } catch { return false; } }","tryCatchPattern":"try { ewwPaths(configPath); } catch (e) { if (String(e).includes('not a file within it')) { configPath = path.dirname(configPath); ewwPaths(configPath); } else { throw e; } }","preventionTips":["Always pass directories to --config, never file paths","In scripts, apply `dirname` before forwarding user-supplied paths","Document that the flag takes a directory in wrappers/aliases"],"tags":["cli","path","config","argument"],"backgroundTag":"invalid-cli-argument","analyzedSha":"48f5aa8b379adf29da0b0bb9ca04164f65d8bdaa","analyzedAt":"2026-09-08T03:13:26.897Z","contentChangedAt":"2026-09-08T03:13:26.897Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}