Morganamilo/paru · error
value can not be empty for key
Error message
value can not be empty for key '{}' What it means
In this crate's pacman.conf INI parser (src/config.rs:941), parse_directive requires a value for every key it processes. When a directive such as `Include` appears with no value after the `=`, the parser bails with "value can not be empty for key '{}'". This is a strict config-validation error: the parser refuses to guess defaults for directives that need an operand (e.g. an Include path pointing at another config fragment).
Solutions
- Open the pacman.conf (and every file it Includes) and give the offending key a value: `Include = /etc/pacman.d/mirrorlist`.
- If the directive is unused, delete the entire line or comment it out with `#` instead of leaving an empty value.
- Regenerate a known-good pacman.conf (e.g. `pacman-conf` output or distro default /etc/pacman.conf) and re-apply customizations.
- Validate the config before use with `pacman-conf` or the crate's parser on a copy so failures are caught early.
Example fix
// before (pacman.conf) Include = // after (pacman.conf) Include = /etc/pacman.d/mirrorlist
Defensive patterns
Strategy: validation
Validate before calling
// Pre-validate pacman.conf lines before handing to the parser
fn validate_no_empty_values(path: &str) -> Result<(), String> {
for (n, line) in std::fs::read_to_string(path)?.lines().enumerate() {
let line = line.trim();
if line.is_empty() || line.starts_with('#') || line.starts_with('[') { continue; }
match line.split_once('=') {
Some((k, v)) if v.trim().is_empty() => {
return Err(format!("line {}: empty value for key '{}'", n + 1, k.trim()))
}
None => return Err(format!("line {}: not key=value: '{}'", n + 1, line)),
_ => {}
}
}
Ok(())
} Prevention
- Never leave `key =` with an empty value; comment out the whole line instead.
- Run `pacman-conf` (or the parser on a scratch copy) after every manual pacman.conf edit.
- Resolve .pacnew/.pacsave merges carefully — empty lines often come from failed merges.
- Keep generated/chroot configs fully templated so placeholders are always substituted.
When it happens
Trigger: Calling pacmanconf::Config::expand_with_opts / parse on a pacman.conf (or any file it Includes) that contains a directive with an empty or missing value — e.g. a line reading just `Include` or `Include =` with nothing after the `=`. ParseArg in src/args.rs and chroot setup in src/chroot.rs:29 both funnel through this parser.
Common situations: Hand-edited pacman.conf where the value was accidentally deleted; a generated pacstrap/chroot pacman.conf template with a placeholder never filled in; a blank `Include =` line left behind after commenting out a repo; copy-paste truncation of the config line.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- key ' ' does not belong to a section
- no local repo named
- no local repos configured, add one to your pacman.conf: …
- can not find local repo
- invalid value ' ' for key ' ', expected
AI-assisted analysis of Morganamilo/paru@9ac3578807 (2026-09-12).
Data as JSON: /api/errors/c21097aea63c320f.
Report an issue: GitHub.
Appendix: source
Thrown at src/config.rs:941
return !(args.has_arg("p", "print")
|| args.has_arg("p", "print-format")
|| args.has_arg("s", "search")
|| args.has_arg("l", "list")
|| args.has_arg("g", "groups")
|| args.has_arg("i", "info")
|| (args.has_arg("c", "clean") && !self.mode.repo()));
} else if self.op == Op::Upgrade || self.op == Op::Build {
return true;
}
false
}
fn parse_directive(&mut self, key: &str, value: Option<&str>) -> Result<()> {
if key == "Include" {
let value = match value {
Some(value) => value,
None => bail!(tr!("value can not be empty for key '{}'", key)),
};
let ini = std::fs::read_to_string(value)?;
let section = self.section.clone();
let section = section.as_deref();
let section = self
.parse_with_section(section, Some(value), &ini)?
.map(|s| s.to_string());
self.section = section;
return Ok(());
}
let section = match &self.section {
Some(section) => section.as_str(),
None => bail!(tr!("key '{}' does not belong to a section", key)),
};
View on GitHub (pinned to 9ac3578807)