{"record":{"id":"e2c9073df6f16985","repo":"router-for-me/CLIProxyAPI","slug":"invalid-plugin-version-q","errorCode":null,"errorMessage":"invalid plugin version %q","messagePattern":"invalid plugin version %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/pluginstore/install.go","lineNumber":95,"sourceCode":"\t\t\treturn InstallResult{}, errPlugin\n\t\t}\n\t\treturn c.InstallDirect(ctx, plugin, plugin.Install, options)\n\tcase InstallTypeGitHubRelease:\n\t\treturn c.InstallVersion(ctx, manifest.Plugin(), manifest.ReleaseTag, manifest.Version, options)\n\tdefault:\n\t\treturn InstallResult{}, fmt.Errorf(\"unsupported install type %q\", manifest.Install.Type)\n\t}\n}\n\n// InstallVersion installs a plugin artifact from a fixed release tag/version.\nfunc (c Client) InstallVersion(ctx context.Context, plugin Plugin, releaseTag string, version string, options InstallOptions) (InstallResult, error) {\n\tif errValidate := ValidatePlugin(plugin); errValidate != nil {\n\t\treturn InstallResult{}, errValidate\n\t}\n\toptions = normalizeInstallOptions(options)\n\tversion = normalizeVersion(version)\n\tif !validPluginVersion(version) {\n\t\treturn InstallResult{}, fmt.Errorf(\"invalid plugin version %q\", version)\n\t}\n\treleaseTag = strings.TrimSpace(releaseTag)\n\tif releaseTag == \"\" {\n\t\treleaseTag = version\n\t}\n\trelease, errRelease := c.FetchReleaseByTag(ctx, plugin, releaseTag)\n\tif errRelease != nil {\n\t\treturn InstallResult{}, errRelease\n\t}\n\treleaseVersion, errVersion := ReleaseVersion(release)\n\tif errVersion != nil {\n\t\treturn InstallResult{}, errVersion\n\t}\n\tif releaseVersion != version {\n\t\treturn InstallResult{}, fmt.Errorf(\"release tag %q resolved version %q, want %q\", releaseTag, releaseVersion, version)\n\t}\n\tplugin.Version = version\n\treturn c.installRelease(ctx, plugin, release, version, options)","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/pluginstore/install.go#L77-L113","documentation":"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.","triggerScenarios":"Calling InstallVersion with version = \"\", \"latest\", \"1\", or characters outside the allowed set; same check in InstallDirect on plugin.Version.","commonSituations":"Passing a release tag where a version is expected; manifest with missing version field; typo'd version like '1..0' or trailing whitespace-only.","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"],"exampleFix":"// before\nresult, err := client.InstallVersion(ctx, plugin, tag, \"latest\", opts)\n\n// after\nrelease, _ := client.FetchReleaseByTag(ctx, plugin, tag)\nversion, err := pluginstore.ReleaseVersion(release) // e.g. \"1.2.3\"\nresult, err := client.InstallVersion(ctx, plugin, tag, version, opts)","handlingStrategy":"validation","validationCode":"// Mirror of the guard: non-empty, semver-shaped (leading v tolerated).\nversion := strings.TrimPrefix(strings.TrimSpace(raw), \"v\")\nif !semverLike(version) { // e.g. regexp `^\\d+\\.\\d+\\.\\d+(-[\\w.]+)?$`\n    return fmt.Errorf(\"invalid plugin version %q\", raw)\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"invalid plugin version\") {\n    // resolve tag -> version via ReleaseVersion, then retry with the concrete version\n}","preventionTips":["Always pass a concrete version (1.2.3), never tags like 'latest'","Resolve tags with FetchReleaseByTag + ReleaseVersion first","Validate manifest version fields in CI"],"tags":["version","validation","install","go"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}