router-for-me/CLIProxyAPI · error
invalid plugin version %q
Error message
invalid plugin version %q
What it means
InstallVersion (and InstallDirect) rejected the version string after normalizeVersion because validPluginVersion failed. Versions must be non-empty semver-like identifiers; a 'v' prefix is normalized away, but empty or malformed strings fail. The quoted value in the message shows the normalized string that was rejected.
Source
Thrown at internal/pluginstore/install.go:95
return InstallResult{}, errPlugin
}
return c.InstallDirect(ctx, plugin, plugin.Install, options)
case InstallTypeGitHubRelease:
return c.InstallVersion(ctx, manifest.Plugin(), manifest.ReleaseTag, manifest.Version, options)
default:
return InstallResult{}, fmt.Errorf("unsupported install type %q", manifest.Install.Type)
}
}
// InstallVersion installs a plugin artifact from a fixed release tag/version.
func (c Client) InstallVersion(ctx context.Context, plugin Plugin, releaseTag string, version string, options InstallOptions) (InstallResult, error) {
if errValidate := ValidatePlugin(plugin); errValidate != nil {
return InstallResult{}, errValidate
}
options = normalizeInstallOptions(options)
version = normalizeVersion(version)
if !validPluginVersion(version) {
return InstallResult{}, fmt.Errorf("invalid plugin version %q", version)
}
releaseTag = strings.TrimSpace(releaseTag)
if releaseTag == "" {
releaseTag = version
}
release, errRelease := c.FetchReleaseByTag(ctx, plugin, releaseTag)
if errRelease != nil {
return InstallResult{}, errRelease
}
releaseVersion, errVersion := ReleaseVersion(release)
if errVersion != nil {
return InstallResult{}, errVersion
}
if releaseVersion != version {
return InstallResult{}, fmt.Errorf("release tag %q resolved version %q, want %q", releaseTag, releaseVersion, version)
}
plugin.Version = version
return c.installRelease(ctx, plugin, release, version, options)View on GitHub (pinned to 78f0c4079e)
Solutions
- Pass a concrete version like '1.2.3' (a leading 'v' is fine — it is normalized)
- If you only have a tag, resolve it to its version first (ReleaseVersion) before calling InstallVersion
- Fix the version field in the plugin manifest
Example fix
// before result, err := client.InstallVersion(ctx, plugin, tag, "latest", opts) // after release, _ := client.FetchReleaseByTag(ctx, plugin, tag) version, err := pluginstore.ReleaseVersion(release) // e.g. "1.2.3" result, err := client.InstallVersion(ctx, plugin, tag, version, opts)
Defensive patterns
Strategy: validation
Validate before calling
// Mirror of the guard: non-empty, semver-shaped (leading v tolerated).
version := strings.TrimPrefix(strings.TrimSpace(raw), "v")
if !semverLike(version) { // e.g. regexp `^\d+\.\d+\.\d+(-[\w.]+)?$`
return fmt.Errorf("invalid plugin version %q", raw)
} Try / catch
if err != nil && strings.Contains(err.Error(), "invalid plugin version") {
// resolve tag -> version via ReleaseVersion, then retry with the concrete version
} Prevention
- Always pass a concrete version (1.2.3), never tags like 'latest'
- Resolve tags with FetchReleaseByTag + ReleaseVersion first
- Validate manifest version fields in CI
When it happens
Trigger: Calling InstallVersion with version = "", "latest", "1", or characters outside the allowed set; same check in InstallDirect on plugin.Version.
Common situations: Passing a release tag where a version is expected; manifest with missing version field; typo'd version like '1..0' or trailing whitespace-only.
Related errors
- invalid plugin id %q
- weight must not exceed %d
- weight must be an integer: %w
- weight must be an integer
- invalid auth file name
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/e2c9073df6f16985.
Report an issue: GitHub.