{"record":{"id":"855b12a397963d65","repo":"slint-ui/slint","slug":"license-symlink-is-not-necessary","errorCode":null,"errorMessage":"LICENSE symlink \"{}\" is not necessary","messagePattern":"LICENSE symlink \"(.+?)\" is not necessary","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"xtask/src/reuse_compliance_check.rs","lineNumber":174,"sourceCode":"        if !is_symlink(&child) {\n            if child.is_file() && fix_it {\n                to_remove.push(child.clone());\n                continue;\n            } else {\n                anyhow::bail!(\"\\\"{}\\\" is a not a symlink!\", child.to_string_lossy());\n            }\n        }\n\n        let ext = child.extension().unwrap_or_default();\n        let file_stem = child.file_stem().unwrap_or_default().to_string_lossy().to_string();\n\n        if ext.is_empty() || (ext != \"txt\" && ext != \"md\" && ext != \"html\") {\n            anyhow::bail!(\"Invalid extension for LICENSE symlink \\\"{}\\\"\", child.to_string_lossy());\n        }\n\n        if file_stem.is_empty() || !licenses.contains(&file_stem) {\n            if !fix_it {\n                anyhow::bail!(\"LICENSE symlink \\\"{}\\\" is not necessary\", child.to_string_lossy());\n            } else {\n                to_remove.push(child.clone());\n                continue;\n            }\n        } else {\n            linked_licenses.push(file_stem.clone());\n        }\n\n        let link_target = std::fs::read_link(&child).with_context(|| {\n            format!(\"Could not extract link target of \\\"{}\\\"\", child.to_string_lossy())\n        })?;\n        let link_target_file_stem = link_target.file_stem().unwrap_or_default().to_string_lossy();\n        let link_target_extension = link_target.extension().unwrap_or_default();\n\n        let validated_link_target = lic_dir.join(&link_target).canonicalize().unwrap_or_default();\n        if validated_link_target.as_os_str().is_empty() {\n            if !fix_it {\n                anyhow::bail!(","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/slint-ui/slint/blob/bb937076de3f7919766c1f25e2e969367cf77e9a/xtask/src/reuse_compliance_check.rs#L156-L192","documentation":"Each symlink in a sub-LICENSES/ directory must correspond to a license actually used by files under that directory, as reported by the parsed SPDX/reuse data (the `licenses` list). This bail fires when a symlink's file stem is not in that list (or is empty), i.e. the link is unnecessary — but only when fix mode is off; with --fix-symlinks the link is silently removed instead.","triggerScenarios":"Running the check without --fix-symlinks while a sub-LICENSES/ dir contains a symlink whose stem matches no license used in that directory (file_stem not in `licenses`), e.g. after removing the only MIT-licensed file but leaving the MIT symlink behind.","commonSituations":"Stale license symlinks left after deleting/refactoring code; a license symlink added manually for a license not detected by reuse (missing SPDX headers/REUSE.toml entries); a typo in the symlink name.","solutions":["Remove the unnecessary symlink from the sub-LICENSES/ directory, or re-run with `--fix-symlinks` to have it removed automatically","If the license IS used, fix the SPDX data: add proper copyright/SPDX headers or REUSE.toml entries so reuse reports that license for the directory","Check for a typo: symlink stem must exactly equal the license identifier, e.g. `BSD-3-Clause.txt`"],"exampleFix":"// before\npackage/LICENSES/MIT.txt -> ../../../LICENSES/MIT.txt   (no MIT-licensed files in package)\n// after\nrm package/LICENSES/MIT.txt","handlingStrategy":"validation","validationCode":"let used: HashSet<String> = licenses_used_in_dir.into_iter().collect();\nlet linked: Vec<String> = std::fs::read_dir(dir.join(\"LICENSES\"))?.filter_map(|e| e.ok()).filter(|e| is_symlink(&e.path())).filter_map(|e| e.path().file_stem()?.to_str().map(str::to_string)).collect();\nlet stale: Vec<_> = linked.iter().filter(|l| !used.contains(*l)).collect();","typeGuard":null,"tryCatchPattern":"if let Err(e) = run_check() {\n    if e.to_string().contains(\"is not necessary\") { /* remove the stale symlink or add SPDX headers so the license is detected */ }\n    else { return Err(e); }\n}","preventionTips":["When removing the last file using a license, also remove its LICENSES/ symlink or run with --fix-symlinks","Keep SPDX headers/REUSE.toml in sync so the license map matches the symlinks","After refactors, run the check without --fix first to see stale links"],"tags":["reuse","symlink","licensing","spdx"],"backgroundTag":"resource-not-found","analyzedSha":"bb937076de3f7919766c1f25e2e969367cf77e9a","analyzedAt":"2026-09-16T01:37:20.251Z","contentChangedAt":"2026-09-16T01:37:20.251Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}