slint-ui/slint · error

Missing LICENSES directory for published crate

Error message

Missing LICENSES directory for published crate {:?}

What it means

For crates that are published, check_licenses_dir expects a LICENSES/ subdirectory in the crate directory containing symlinks to the license texts. If the directory doesn't exist and the check isn't in fix mode, this error is thrown.

Solutions

  1. Run `cargo xtask check --fix`, which creates the missing LICENSES directory (and symlinks)
  2. Manually create <crate>/LICENSES/ and symlink the required license files, e.g. `ln -s ../../LICENSES/MIT.txt LICENSES/MIT.txt`
  3. Ensure the crate directory was fully committed (LICENSES is symlinked content that git must track)

Example fix

# before
my-crate/Cargo.toml
src/
# after
mkdir -p my-crate/LICENSES
ln -s ../../LICENSES/MIT.txt my-crate/LICENSES/MIT.txt
Defensive patterns

Strategy: validation

Validate before calling

let is_published = /* from publish flag/workspace */ true;
if is_published {
    assert!(std::path::Path::new("my-crate/LICENSES").is_dir(), "missing LICENSES dir");
}

Type guard

fn licenses_dir_exists(crate_dir: &std::path::Path) -> bool {
    crate_dir.join("LICENSES").is_dir()
}

Prevention

When it happens

Trigger: Running `cargo xtask check` (no --fix) on a publishable crate whose directory lacks a LICENSES/ folder; a new crate added without creating the directory.

Common situations: Scaffolding a new publishable crate; deleting LICENSES/ accidentally; moving a crate without copying its directory contents.

Related errors


AI-assisted analysis of slint-ui/slint@3a7e700487 (2026-09-16). Data as JSON: /api/errors/c0071edbf92e161e. Report an issue: GitHub.

Appendix: source

Thrown at xtask/src/license_headers_check.rs:1095

                None => {
                    return Err(anyhow!(
                        "No license file found in root LICENSES/ for SPDX id '{}'",
                        id
                    ));
                }
            }
        }

        if !licenses_dir.exists() {
            if self.fix_it {
                eprintln!(
                    "Fixing up {:?} as instructed. Creating missing LICENSES directory.",
                    crate_dir
                );
                std::fs::create_dir(&licenses_dir)
                    .context("Failed to create LICENSES directory")?;
            } else {
                return Err(anyhow!(
                    "Missing LICENSES directory for published crate {:?}",
                    crate_dir
                ));
            }
        }

        // Compute relative path after directory exists so canonicalize works
        let rel_prefix = diff_paths(&root_licenses, &licenses_dir);

        for filename in &expected_filenames {
            let symlink_path = licenses_dir.join(filename);
            let expected_target = rel_prefix.join(filename);

            if let Ok(meta) = std::fs::symlink_metadata(&symlink_path) {
                if !meta.file_type().is_symlink() {
                    return Err(anyhow!("{:?} exists but is not a symlink", symlink_path));
                }
                let target = std::fs::read_link(&symlink_path)

View on GitHub (pinned to 3a7e700487)