jdx/mise · error

vfox plugin archive must contain metadata.lua at its root

Error message

vfox plugin archive must contain metadata.lua at its root

What it means

After a vfox plugin archive is extracted, mise validates its layout: `metadata.lua` must exist as a regular file at the extraction root. The metadata file declares the plugin's name, versions, and install logic, so a plugin without it cannot function. This error means the archive extracted but is not a valid vfox plugin layout.

Source

Thrown at src/plugins/packslip.rs:240

                continue;
            }
            let Component::Normal(name) = component else {
                bail!("vfox plugin archive contains an unsafe path");
            };
            let name = name.to_string_lossy();
            ensure!(
                !name.contains(['\\', ':'])
                    && !name.eq_ignore_ascii_case(".git")
                    && !name.eq_ignore_ascii_case(STATE_FILE),
                "vfox plugin archive contains a reserved or unsafe path"
            );
        }
    }
    Ok(())
}

pub(crate) fn validate_layout(path: &Path) -> Result<()> {
    ensure!(
        path.join("metadata.lua").is_file(),
        "vfox plugin archive must contain metadata.lua at its root"
    );
    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn plugin_artifact_contract() {
        let payload = packslip::sigstore::peek_statement(include_str!(
            "../../test/fixtures/packslip-vfox/packslip.sigstore.json"
        ))
        .unwrap();
        let mut statement: packslip::model::Statement = serde_json::from_slice(&payload).unwrap();
        let artifact = statement.predicate.artifacts.remove(0);

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Repackage so metadata.lua sits at the archive root: `tar -czf plugin.tar.gz -C my-plugin .`.
  2. Confirm metadata.lua actually exists in the plugin repository and is named exactly `metadata.lua`.
  3. Ensure metadata.lua is a regular file, not a symlink or directory.

Example fix

// before: tar -czf plugin.tar.gz my-plugin/    -> my-plugin/metadata.lua
// after
tar -czf plugin.tar.gz -C my-plugin .        -> metadata.lua
Defensive patterns

Strategy: validation

Validate before calling

# shell: verify the archive layout before publishing/installing
tar -tzf plugin.tar.gz | grep -qx 'metadata.lua' && echo OK || echo 'REJECTED: metadata.lua not at archive root'

Prevention

When it happens

Trigger: Installing/parsing a vfox plugin packslip archive where metadata.lua is missing, is in a subdirectory (e.g. plugin-name/metadata.lua), or exists only as a symlink/directory rather than a file.

Common situations: Plugin author archives the repo root including a wrapping top-level directory from `tar -czf out.tar.gz my-plugin/`, or the metadata file was renamed/deleted, or only source.lua files were packaged.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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