o2sh/onefetch · error

Could not initialize the license detector

Error message

Could not initialize the license detector: {}

What it means

This error is raised by Detector::new() when askalono's Store::from_cache() fails to deserialize the bundled license cache (resources/license.cache.zstd, embedded via include_bytes! at compile time). It means the license detector could not be constructed, so license detection for a repository cannot proceed. Because the cache is compiled into the binary, this almost always indicates a corrupted, truncated, missing, or incompatible cache file in the crate itself, or an askalono version mismatch producing an unreadable cache format.

Solutions

  1. Verify resources/license.cache.zstd exists, is non-empty, and is a valid zstd file in the crate checkout; restore it from the upstream repo if damaged.
  2. Run `cargo clean` and rebuild to ensure the embedded bytes match the current resource file.
  3. Regenerate the license cache with the same askalono version the Cargo.toml depends on (askalono's cache/`store` tooling), then rebuild.
  4. Pin or align the askalono dependency version with the version used to produce the cache; a mismatched format cannot be deserialized.
  5. If the error persists in a fork, check that include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/resources/license.cache.zstd")) points at the intended file for your build layout.
  6. As a last resort, wrap Detector::new() and degrade gracefully (skip license info) instead of failing the whole run.

Example fix

// before
let detector = Detector::new()?;
// after
let detector = match Detector::new() {
    Ok(d) => Some(d),
    Err(e) => {
        eprintln!("license detection unavailable: {e}");
        None
    }
};
Defensive patterns

Strategy: try-catch

Validate before calling

// Before calling Detector::new(), verify the embedded cache is present and valid zstd:
fn license_cache_looks_valid() -> bool {
    // CACHE_DATA is include_bytes!-embedded; a healthy build always has non-empty bytes
    !CACHE_DATA.is_empty()
}

Type guard

fn detector_available() -> Option<Detector> {
    Detector::new().ok()
}

Try / catch

match Detector::new() {
    Ok(detector) => detector.get_license(dir, manifest),
    Err(e) if e.to_string().contains("Could not initialize the license detector") => {
        // fall back: report license as unknown, don't abort the whole info run
        eprintln!("license detector unavailable: {e}");
        Ok("unknown".to_string())
    }
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: Calling onefetch's license detection (e.g. Detector::new() or any info rendering that constructs the detector) when Store::from_cache cannot decompress/parse the embedded zstd license cache — e.g. the resources/license.cache.zstd file was corrupted, replaced with an empty or invalid file, generated by an incompatible askalono version, or the include_bytes! path broke in a modified build.

Common situations: Building the crate after modifying or deleting resources/license.cache.zstd; regenerating the cache with a different askalono version whose cache serialization format is incompatible; a source distribution (crates.io package) missing the resources file; an interrupted or tampered build where the embedded bytes are wrong; vendored/forked builds that broke CARGO_MANIFEST_DIR-relative include_bytes! resolution.


AI-assisted analysis of o2sh/onefetch@b566c097a1 (2026-09-08). Data as JSON: /api/errors/dbc0e7bc64bc99eb. Report an issue: GitHub.

Appendix: source

Thrown at src/info/license.rs:26

const LICENSE_FILES: [&str; 3] = ["LICENSE", "LICENCE", "COPYING"];

static CACHE_DATA: &[u8] = include_bytes!(concat!(
    env!("CARGO_MANIFEST_DIR"),
    "/resources/license.cache.zstd"
));
const MIN_THRESHOLD: f32 = 0.8;

pub struct Detector {
    store: Store,
}

impl Detector {
    pub fn new() -> Result<Self> {
        match Store::from_cache(CACHE_DATA) {
            Ok(store) => Ok(Self { store }),
            Err(e) => {
                bail!("Could not initialize the license detector: {}", e)
            }
        }
    }

    fn get_license(&self, dir: &Path, manifest: Option<&Manifest>) -> Result<String> {
        let license_from_manifest = manifest.and_then(|m| m.license.clone()).unwrap_or_default();
        if license_from_manifest.is_empty() {
            let mut output = fs::read_dir(dir)?
                .filter_map(std::result::Result::ok)
                .map(|entry| entry.path())
                .filter(|entry| {
                    entry.is_file()
                        && entry
                            .file_name()
                            .map(OsStr::to_string_lossy)
                            .is_some_and(is_license_file)
                })
                .filter_map(|entry| {

View on GitHub (pinned to b566c097a1)