espanso/espanso · error

unable to find version: {} for package: {}

Error message

unable to find version: {} for package: {}

What it means

After filtering by name and sorting versions, resolve_package selects either the explicit requested version or the newest. If nothing is selected (usually the explicit version is not among the available ones) it bails with this error naming the version and package.

Source

Thrown at espanso-package/src/resolver.rs:61

    if matching_packages.is_empty() {
        bail!("no package found with name: {}", name);
    }

    matching_packages.sort_by(|a, b| natord::compare(&a.manifest.version, &b.manifest.version));

    let matching_package = if let Some(explicit_version) = version {
        matching_packages
            .into_iter()
            .find(|package| package.manifest.version == explicit_version)
    } else {
        matching_packages.into_iter().next_back()
    };

    if let Some(matching_package) = matching_package {
        Ok(matching_package)
    } else {
        bail!(
            "unable to find version: {} for package: {}",
            version.unwrap_or_default(),
            name
        );
    }
}

pub fn resolve_all_packages(base_dir: &Path) -> Result<Vec<ResolvedPackage>> {
    let manifest_files = find_all_manifests(base_dir)?;

    if manifest_files.is_empty() {
        bail!("no manifests found in base_dir");
    }

    let mut manifests = Vec::new();

    for manifest_file in manifest_files {
        let base_dir = manifest_file

View on GitHub (pinned to e6c3736675)

Solutions

  1. List available versions in the package manifests and use an exact existing version string.
  2. Pass version=None to get the latest available version instead of pinning.
  3. Update/refresh the package index or re-download the package to fetch newer versions.
  4. Check version format — versions are compared with natural ordering, so use the exact "x.y.z" string from the manifest.

Example fix

// before
resolve_package(base_dir, "emoji", Some("2.0.0"))
// after
resolve_package(base_dir, "emoji", Some("1.6.0")) // version present in manifests
// or
resolve_package(base_dir, "emoji", None)
Defensive patterns

Strategy: validation

Validate before calling

// verify the version exists before pinning
let versions: Vec<_> = resolve_all_packages(base_dir)?
    .iter().filter(|p| p.manifest.name == name)
    .map(|p| p.manifest.version.clone()).collect();
if let Some(v) = requested_version { assert!(versions.contains(&v.to_string()), "version {v} unavailable"); }

Try / catch

match resolve_package(base_dir, name, Some(ver)) {
    Err(e) if e.to_string().contains("unable to find version") => resolve_package(base_dir, name, None),
    other => other,
}

Prevention

When it happens

Trigger: Calling resolve_package with version=Some(v) where v does not exist for that package in the local manifests (e.g. "1.2.3" when only 1.0.0 is installed), or with an empty/absent set that yields no candidate.

Common situations: Pinning an old version that has since been removed; typo in the version string; version format mismatch ("1.2" vs "1.2.0"); package index stale so the newest version is not present locally.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of espanso/espanso@e6c3736675 (2026-09-06). Data as JSON: /api/errors/76c52c1ef3dc4ddb. Report an issue: GitHub.