jdx/mise · error

lazy tool {} has no registry bin metadata; set lazy_bins exp

Error message

lazy tool {} has no registry bin metadata; set lazy_bins explicitly

What it means

When a tool request is marked lazy, mise needs the tool's executable bin names to create lazy shims. It tries registry bin metadata first; if the registry has no bins for the tool and lazy_bins wasn't set explicitly, mise cannot know what to shim and bails.

Source

Thrown at src/toolset/tool_request.rs:310

    /// Command names that should receive bootstrap shims before a lazy tool is installed.
    /// Registry metadata is authoritative when the config does not provide an explicit list.
    pub(crate) fn lazy_bins(&self) -> Result<Option<Vec<String>>> {
        let options = self.resolved_options().effective();
        if options.lazy != Some(true) {
            return Ok(None);
        }
        if !options.lazy_bins.is_empty() {
            return Ok(Some(options.lazy_bins.clone()));
        }
        if let Some(tool) = self.ba().registry_tool()
            && !tool.bins.is_empty()
        {
            return Ok(Some(
                tool.bins.iter().map(|bin| (*bin).to_string()).collect(),
            ));
        }
        bail!(
            "lazy tool {} has no registry bin metadata; set lazy_bins explicitly",
            self.ba().short
        )
    }

    pub(crate) fn explicit_options(&self) -> ToolVersionOptions {
        self.resolved_options().options_from_sources(&[
            ToolOptionSource::Request,
            ToolOptionSource::InlineBackendArg,
        ])
    }

    fn resolved_options(&self) -> &ResolvedToolOptions {
        match self {
            Self::Version { options: o, .. }
            | Self::Prefix { options: o, .. }
            | Self::Ref { options: o, .. }
            | Self::Sub { options: o, .. }

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Set lazy_bins explicitly for the tool (e.g. in the tool's config/registry entry) listing its executables
  2. Add `bins` metadata to the tool's registry entry
  3. Disable lazy shims for that tool if bin names are unknown
  4. Update the plugin/registry entry so it declares its bins

Example fix

// before (registry entry without bins)
[tools.mytool]
backend = 'github:me/mytool'
// after
[tools.mytool]
backend = 'github:me/mytool'
bins = ['mytool']
Defensive patterns

Strategy: validation

Validate before calling

// ensure registry metadata declares bins before enabling lazy shims
if (!registryEntry.bins || registryEntry.bins.length === 0) config.lazy_bins = explicitBins;

Type guard

const hasBins = (t) => Array.isArray(t.bins) && t.bins.length > 0;

Try / catch

try { lazyBins(req) } catch (e) { if (String(e).includes('no registry bin metadata')) { fallbackToNonLazyInstall(req); } else { throw e; } }

Prevention

When it happens

Trigger: Calling ToolRequest::lazy_bins for a lazy tool where the registry entry has empty bins and no explicit lazy_bins were provided — i.e. a registry/short entry lacking 'bins' metadata while lazy shims are enabled.

Common situations: Custom or newly-added registry tools missing bins metadata in mise.plugin.toml/registry; enabling lazy shims for a tool the registry doesn't describe; a plugin without declared bins.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/7690951c19f9e054. Report an issue: GitHub.