router-for-me/CLIProxyAPI · error
invalid release tag %q
Error message
invalid release tag %q
What it means
ReleaseVersion converts a GitHub release TagName into a plugin version: normalizeVersion strips a leading v/V, then validPluginVersion checks the result. 'invalid release tag %q' means the tag — after stripping the prefix — is not an acceptable plugin version string. The raw tag is included in the error for diagnostics.
Source
Thrown at internal/pluginstore/github.go:115
url.PathEscape(tag),
)
data, errDownload := c.get(ctx, releaseURL, "application/vnd.github+json", RequestKindMetadata, 0)
if errDownload != nil {
return Release{}, errDownload
}
var release Release
if errDecode := json.Unmarshal(data, &release); errDecode != nil {
return Release{}, fmt.Errorf("decode release: %w", errDecode)
}
return release, nil
}
// ReleaseVersion derives the plugin version from the release tag, stripping a
// leading "v"/"V" and validating the result.
func ReleaseVersion(release Release) (string, error) {
version := normalizeVersion(release.TagName)
if !validPluginVersion(version) {
return "", fmt.Errorf("invalid release tag %q", release.TagName)
}
return version, nil
}
func (c Client) DownloadAsset(ctx context.Context, asset ReleaseAsset) ([]byte, error) {
downloadURL := strings.TrimSpace(asset.BrowserDownloadURL)
apiURL := strings.TrimSpace(asset.APIURL)
if downloadURL == "" || c.releaseAssetAPIAuthenticated(apiURL) {
if apiURL != "" {
downloadURL = apiURL
}
}
if downloadURL == "" {
return nil, fmt.Errorf("asset %q missing download url", asset.Name)
}
return c.get(ctx, downloadURL, "application/octet-stream", RequestKindArtifact, 0)
}
View on GitHub (pinned to 78f0c4079e)
Solutions
- Retag the release using a version the validator accepts, e.g. 'v1.2.3' instead of 'v1' or 'stable'.
- Check validPluginVersion in internal/pluginstore to see the exact accepted grammar before choosing a tag scheme.
- If you cannot control the tag, map it to a synthetic version before invoking release-based install.
Example fix
# before git tag stable && git push --tags # install fails: 'invalid release tag "stable"' # after git tag v1.2.3 && git push --tags # install derives version 1.2.3
Defensive patterns
Strategy: validation
Validate before calling
v := strings.TrimPrefix(strings.TrimPrefix(strings.TrimSpace(release.TagName), "v"), "V")
if !looksLikeVersion(v) { // e.g. regexp ^\d+\.\d+\.\d+
return fmt.Errorf("release tag %q is not a version — retag as vX.Y.Z", release.TagName)
} Type guard
func releaseTagIsVersion(tag string) bool {
v := strings.TrimPrefix(strings.TrimPrefix(strings.TrimSpace(tag), "v"), "V")
matched, _ := regexp.MatchString(`^\d+\.\d+\.\d+(-[\w.]+)?$`, v)
return matched
} Prevention
- Adopt strict semver tags (vMAJOR.MINOR.PATCH) in release automation.
- Reject non-version tags at CI time, before users can install them.
When it happens
Trigger: A release tagged with something that is not a valid version after v/V stripping — e.g. 'v', 'latest', 'nightly-2024', 'release-1' or tags with whitespace/special characters, depending on validPluginVersion's rules (typically semver-like).
Common situations: Plugin maintainers tagging releases as 'stable', 'prod', or date-only tags; automation creating ad-hoc tags; tags like 'v2' (incomplete semver) if the validator requires full MAJOR.MINOR.PATCH.
Related errors
- decode release: %w
- release tag is required
- asset %q missing download url
- unexpected status %d
- unexpected status %d: %s
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/81c5c507ae47c17b.
Report an issue: GitHub.