jdx/mise · warning · eyre::Report
systemDependencies entry must set exactly one of bin/pkgconf
Error message
systemDependencies entry must set exactly one of bin/pkgconfig/sharedlib/command
What it means
A vfox plugin's PLUGIN.systemDependencies entries describe host prerequisites as capability checks. Each entry must set exactly one of bin (PATH executable), pkgconfig (.pc module), sharedlib (soname), or command (exit-0 shell command). Setting none or more than one fails this conversion; mise then warns and skips the bad entry while keeping the rest of the plugin usable, so this is surfaced as a warning, not a fatal error.
Source
Thrown at src/system/deps.rs:197
pub struct DepStatus {
pub dep: SystemDep,
/// detected version, if a version was extracted
pub found: Option<String>,
pub satisfied: bool,
/// why it is unsatisfied (or a note when satisfied)
pub reason: Option<String>,
}
impl TryFrom<vfox::SystemDependency> for SystemDep {
type Error = eyre::Error;
fn try_from(d: vfox::SystemDependency) -> eyre::Result<Self> {
let check = match (&d.bin, &d.pkgconfig, &d.sharedlib, &d.command) {
(Some(b), None, None, None) => SystemDepCheck::Bin(b.clone()),
(None, Some(p), None, None) => SystemDepCheck::PkgConfig(p.clone()),
(None, None, Some(s), None) => SystemDepCheck::SharedLib(s.clone()),
(None, None, None, Some(c)) => SystemDepCheck::Command(c.clone()),
_ => eyre::bail!(
"systemDependencies entry must set exactly one of bin/pkgconfig/sharedlib/command"
),
};
// A version constraint is only meaningful for bin/pkgconfig (we probe
// `--version` / `--modversion`). If declared on sharedlib/command,
// keep the check but drop the version with a warning rather than
// silently honoring a constraint that is never enforced.
let version = match (&check, &d.version) {
(_, None) => None,
(SystemDepCheck::Bin(_) | SystemDepCheck::PkgConfig(_), Some(v)) => {
Some(VersionConstraint::parse(v)?)
}
(check, Some(_)) => {
warn!(
"systemDependencies: `version` is only supported for bin/pkgconfig checks, ignoring it for the {} check",
check.kind()
);
NoneView on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Keep exactly one check field per entry — split combined checks into multiple entries
- Use bin for executables, pkgconfig for compiled-library modules, sharedlib for sonames, command as the compound escape hatch
- Reload plugin metadata (`mise plugins install --force` or re-resolve) after fixing the Lua table
Example fix
-- before (plugin .lua PLUGIN table)
systemDependencies = {
{ bin = "gcc", pkgconfig = "libxml-2.0" },
}
-- after
systemDependencies = {
{ bin = "gcc" },
{ pkgconfig = "libxml-2.0" },
} Defensive patterns
Strategy: type-guard
Type guard
-- in plugin tests / CI: validate each entry before shipping
for _, dep in ipairs(PLUGIN.systemDependencies or {}) do
local n = (dep.bin and 1 or 0) + (dep.pkgconfig and 1 or 0)
+ (dep.sharedlib and 1 or 0) + (dep.command and 1 or 0)
assert(n == 1, 'systemDependencies entry must set exactly one of bin/pkgconfig/sharedlib/command')
end Prevention
- One capability per systemDependencies entry; split stacks into several entries
- Use the command escape hatch for anything not expressible as bin/pkgconfig/sharedlib
- Test plugin metadata load with `mise registry generate`/plugin test after editing
When it happens
Trigger: A plugin's Lua PLUGIN table contains an empty dependency table {}, or combines checks like { bin = "gcc", pkgconfig = "libxml-2.0" }, in the systemDependencies list.
Common situations: Plugin authors writing new systemDependencies metadata; assuming more fields means OR/AND semantics; copy-pasting an entry and forgetting to delete the other kind fields.
Related errors
- vfox-backend plugin '{plugin_name}' exists but '{tool_name}'
- trimPrefix requires exactly 2 arguments
- unsupported remote cache digest algorithm
- invalid remote cache digest
- invalid remote action manifest ETag
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/5406b4821701efdf.
Report an issue: GitHub.