Morganamilo/paru · error

key ' ' does not belong to a section

Error message

key '{}' does not belong to a section

What it means

src/config.rs:957 throws "key '{}' does not belong to a section" when parse_directive encounters a key=value pair while self.section is None — i.e. a directive appears before any [Section] header in the INI file. INI semantics here require every key to live inside a section (e.g. [options] or [repo-name]); a bare key at the top of the file is rejected rather than implicitly assigned.

Solutions

  1. Move the offending key=value line under an existing section (usually `[options]` or the relevant `[repo]`).
  2. Re-add the missing `[options]` (or other) section header above the key.
  3. Compare against the distro default pacman.conf / .pacnew file to restore proper section structure.
  4. Validate with `pacman-conf` before handing the file to the parser.

Example fix

// before (pacman.conf)
ParallelDownloads = 5
[options]
...

// after (pacman.conf)
[options]
ParallelDownloads = 5
...
Defensive patterns

Strategy: validation

Validate before calling

// Ensure every key line appears after at least one [section] header
fn validate_sections(path: &str) -> Result<(), String> {
    let mut in_section = false;
    for (n, line) in std::fs::read_to_string(path)?.lines().enumerate() {
        let line = line.trim();
        if line.is_empty() || line.starts_with('#') { continue; }
        if line.starts_with('[') && line.ends_with(']') { in_section = true; continue; }
        if !in_section {
            return Err(format!("line {}: key outside any section: '{}'", n + 1, line));
        }
    }
    Ok(())
}

Prevention

When it happens

Trigger: Parsing a pacman.conf where a `key = value` line occurs before the first `[section]` header — commonly caused by prepending lines above `[options]`, deleting the section header, or an Include'd file whose keys are expected to belong to the includer's section but start with their own un-sectioned keys.

Common situations: Manually adding a setting at the very top of pacman.conf; editing scripts that rewrite the file and accidentally drop the `[options]` line; concatenating config fragments without section headers; corruption during package merge of /etc/pacman.conf.pacnew.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of Morganamilo/paru@9ac3578807 (2026-09-12). Data as JSON: /api/errors/4393874c2392d271. Report an issue: GitHub.

Appendix: source

Thrown at src/config.rs:957

            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)),
        };

        let section = section.to_string();

        match section.as_str() {
            "options" => self.parse_option(key, value),
            "bin" => self.parse_bin(key, value),
            "env" => self.parse_env(key, value),
            repo => self.parse_repo(repo, key, value),
        }
    }

    fn parse_repo(&mut self, repo: &str, key: &str, value: Option<&str>) -> Result<()> {
        let value = value.context(tr!("key can not be empty"));

        let repo = self.pkgbuild_repos.repo_mut(repo).unwrap();

        match key {

View on GitHub (pinned to 9ac3578807)