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

  1. Retag the release using a version the validator accepts, e.g. 'v1.2.3' instead of 'v1' or 'stable'.
  2. Check validPluginVersion in internal/pluginstore to see the exact accepted grammar before choosing a tag scheme.
  3. 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

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


AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15). Data as JSON: /api/errors/81c5c507ae47c17b. Report an issue: GitHub.