slint-ui/slint · error

Invalid Cargo.toml -- cannot find package section

Error message

Invalid Cargo.toml -- cannot find package section

What it means

CargoToml::package() was called on a non-workspace manifest (no [workspace] table) that also has no [package] table, so there is no package section to inspect. This makes the Cargo.toml unusable for the license/version field check, which needs a concrete package.

Solutions

  1. Add the [package] table (with name, version, license, etc.) to the Cargo.toml.
  2. Check the manifest path being processed; a virtual [workspace]-only root must be treated via the workspace branch, not the package branch.
  3. If this file is not a real crate manifest, exclude it from the xtask check's file walk.
  4. Validate the TOML parses as expected: [package] must be a table, not e.g. package = "...".

Example fix

// before: manifest without a package table
[workspace]
members = ["crates/*"]

// after: for a member crate, add the section
[package]
name = "my-crate"
version = "1.0.0"
license = "MIT"
Defensive patterns

Strategy: validation

Validate before calling

fn has_package(doc: &toml_edit::DocumentMut) -> bool {
    doc.as_table().get("package").and_then(|p| p.as_table()).is_some()
}
// skip manifests with neither [package] nor [workspace]
if !has_package(&doc) && doc.as_table().get("workspace").is_none() {
    return Ok(());
}

Type guard

fn package_table(doc: &toml_edit::DocumentMut) -> Option<&toml_edit::Table> {
    doc.as_table().get("package")?.as_table()
}

Try / catch

match cargo_toml.package() {
    Ok(pkg) => check_fields(pkg),
    Err(e) if e.to_string().ends_with("cannot find package section") => {
        eprintln!("skipping non-package manifest {}", cargo_toml.path.display());
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: package() (via check_and_fix_package_string_field or published) runs on a manifest without [workspace] whose top-level [package] table is missing or is not a TOML table.

Common situations: A virtual workspace root manifest ([workspace] only) is handled elsewhere, but a stray Cargo.toml with neither section (e.g. a template or generated file) enters the check; manual edits deleted the [package] table; the wrong file was picked up by the manifest glob.

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 slint-ui/slint@3a7e700487 (2026-09-16). Data as JSON: /api/errors/3224748d63ae257a. Report an issue: GitHub.

Appendix: source

Thrown at xtask/src/license_headers_check.rs:821

                .unwrap())
        }
    }

    fn package(&self) -> Result<&toml_edit::Table> {
        if self.is_workspace() {
            self.doc
                .as_table()
                .get("workspace")
                .and_then(|w| w.as_table())
                .and_then(|w| w.get("package"))
                .and_then(|p| p.as_table())
                .ok_or_else(|| anyhow!("Invalid Cargo.toml -- cannot find workspace package section in workspace file"))
        } else {
            self.doc
                .as_table()
                .get("package")
                .and_then(|p| p.as_table())
                .ok_or_else(|| anyhow!("Invalid Cargo.toml -- cannot find package section"))
        }
    }

    fn dependencies(&self, dep_type: &str) -> Vec<(String, CargoDependency)> {
        let table = if self.is_workspace() {
            self.doc
                .as_table()
                .get("workspace")
                .and_then(|w| w.as_table())
                .and_then(|w| w.get(dep_type))
                .and_then(|d| d.as_table())
        } else {
            self.doc.as_table().get(dep_type).and_then(|d| d.as_table())
        };
        match table {
            Some(dep_table) => dep_table
                .iter()
                .filter_map(|(name, entry)| {

View on GitHub (pinned to 3a7e700487)