{"record":{"id":"4285b77052fb5a28","repo":"slint-ui/slint","slug":"no-license-file-found-in-root-licenses-for-spdx-id","errorCode":null,"errorMessage":"No license file found in root LICENSES/ for SPDX id '{}'","messagePattern":"No license file found in root LICENSES/ for SPDX id '(.+?)'","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"xtask/src/license_headers_check.rs","lineNumber":1078,"sourceCode":"            .filter_map(|e| {\n                let path = e.path();\n                let stem = path.file_stem()?.to_string_lossy().to_string();\n                let filename = path.file_name()?.to_string_lossy().to_string();\n                Some((stem, filename))\n            })\n            .collect();\n\n        let spdx_ids: Vec<&str> =\n            license.split(\" OR \").flat_map(|s| s.split(\" AND \")).map(|s| s.trim()).collect();\n\n        let mut expected_filenames: Vec<String> = Vec::new();\n        for id in &spdx_ids {\n            let filename =\n                root_license_files.iter().find(|(stem, _)| stem == id).map(|(_, f)| f.clone());\n            match filename {\n                Some(f) => expected_filenames.push(f),\n                None => {\n                    return Err(anyhow!(\n                        \"No license file found in root LICENSES/ for SPDX id '{}'\",\n                        id\n                    ));\n                }\n            }\n        }\n\n        if !licenses_dir.exists() {\n            if self.fix_it {\n                eprintln!(\n                    \"Fixing up {:?} as instructed. Creating missing LICENSES directory.\",\n                    crate_dir\n                );\n                std::fs::create_dir(&licenses_dir)\n                    .context(\"Failed to create LICENSES directory\")?;\n            } else {\n                return Err(anyhow!(\n                    \"Missing LICENSES directory for published crate {:?}\",","sourceCodeStart":1060,"sourceCodeEnd":1096,"githubUrl":"https://github.com/slint-ui/slint/blob/3a7e700487dc74d404cad0726378053ab763d4e0/xtask/src/license_headers_check.rs#L1060-L1096","documentation":"check_licenses_dir maps the crate's SPDX license identifiers (from the license field) to files in the repository root LICENSES/ directory; it errors if an SPDX id has no matching license text file there.","triggerScenarios":"A crate's Cargo.toml license field contains an SPDX id (split on OR) for which no file named <id>.* exists under root LICENSES/ — e.g. license = \"MIT OR Apache-2.0\" but LICENSES/ only has MIT.txt and Apache-2.0.txt, and the license uses a new id like LicenseRef-Slint-... without a corresponding file.","commonSituations":"Adding a new license expression to a crate without adding the license text to the central LICENSES/ directory; typo in an SPDX id.","solutions":["Add the license text file to the root LICENSES/ directory named after the SPDX id (e.g. LICENSES/MIT.txt)","Fix the SPDX id in the crate's license field if it was misspelled","Verify how ids are matched to file stems in check_licenses_dir and follow the naming convention"],"exampleFix":"// before (Cargo.toml)\nlicense = \"MIT OR BSL-1.0\"   // no LICENSES/BSL-1.0.txt exists\n// after\nlicense = \"MIT OR Apache-2.0\"  // or add LICENSES/BSL-1.0.txt","handlingStrategy":"validation","validationCode":"let license = \"MIT OR Apache-2.0\"; // from Cargo.toml\nfor id in license.split(\" OR \") {\n    let found = std::fs::read_dir(\"LICENSES\")?\n        .filter_map(Result::ok)\n        .any(|e| e.path().file_stem().map_or(false, |s| s == id));\n    assert!(found, \"LICENSES/{id}.* missing\");\n}","typeGuard":"fn spdx_id_has_file(id: &str, dir: &std::path::Path) -> bool {\n    std::fs::read_dir(dir).map_or(false, |rd| rd.filter_map(Result::ok)\n        .any(|e| e.path().file_stem().map_or(false, |s| s == id)))\n}","tryCatchPattern":null,"preventionTips":["When adding a new license expression, add its text to root LICENSES/ in the same commit","Validate SPDX ids with `cargo license` or SPDX tooling","Don't invent LicenseRef-* ids without registering the text file","Keep the license field consistent with the LICENSES/ directory contents"],"tags":["spdx","license","file-not-found","ci"],"backgroundTag":"resource-not-found","analyzedSha":"3a7e700487dc74d404cad0726378053ab763d4e0","analyzedAt":"2026-09-16T01:37:20.251Z","contentChangedAt":"2026-09-16T01:37:20.251Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}