jeessy2/ddns-go · error

the %s, it's not a semantic version

Error message

the %s, it's not a semantic version

What it means

NewVersion parses a version string and returns an error when the input does not match the semantic-version regex. The library attempts to coerce SemVer-like strings, but if the regex (versionRegex.FindStringSubmatch) finds no match it rejects the input with this message including the offending string. It is thrown at parse time, before any numeric field parsing.

Source

Thrown at util/semver/version.go:37

	`(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` +
	`(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?`

// Version 表示单独的语义化版本。
type Version struct {
	major, minor, patch uint64
}

func init() {
	versionRegex = regexp.MustCompile("^" + semVerRegex + "$")
}

// NewVersion 解析给定的版本并返回 Version 实例,如果
// 无法解析该版本则返回错误。如果版本是类似于 SemVer 的版本,则会
// 尝试将其转换为 SemVer。
func NewVersion(v string) (*Version, error) {
	m := versionRegex.FindStringSubmatch(v)
	if m == nil {
		return nil, fmt.Errorf("the %s, it's not a semantic version", v)
	}

	sv := &Version{}

	var err error
	sv.major, err = strconv.ParseUint(m[1], 10, 64)
	if err != nil {
		return nil, fmt.Errorf("解析版本号时出错:%s", err)
	}

	if m[2] != "" {
		sv.minor, err = strconv.ParseUint(strings.TrimPrefix(m[2], "."), 10, 64)
		if err != nil {
			return nil, fmt.Errorf("解析版本号时出错:%s", err)
		}
	} else {
		sv.minor = 0
	}

View on GitHub (pinned to 5874c2e666)

Solutions

  1. Print/validate the input string before parsing — the offending value is quoted in the error message
  2. Trim prefixes like "v" or surrounding whitespace and strip non-semver text before calling NewVersion
  3. Use the library's coercion-friendly format (major[.minor][.patch]) e.g. convert "1.2" or "1" instead of arbitrary strings
  4. Fall back to a default version or skip comparison when the string is unparseable

Example fix

// before
v, err := NewVersion(output) // output = "version 1.2.3"
// after
trimmed := strings.TrimSpace(strings.TrimPrefix(output, "version "))
v, err := NewVersion(trimmed)
Defensive patterns

Strategy: validation

Validate before calling

func looksSemver(v string) bool {
    v = strings.TrimSpace(strings.TrimPrefix(v, "v"))
    parts := strings.Split(v, ".")
    if len(parts) == 0 || len(parts) > 3 { return false }
    for _, p := range parts {
        if p == "" { return false }
        if _, err := strconv.ParseUint(p, 10, 64); err != nil { return false }
    }
    return true
}

Try / catch

v, err := semver.NewVersion(input)
if err != nil {
    log.Warnf("unparseable version %q, skipping comparison", input)
    return nil // or use a default version
}

Prevention

When it happens

Trigger: Calling util/semver.NewVersion with a string that does not match the semver pattern, e.g. "abc", "", "1.2.3.4.5", "v" alone, or a string with invalid characters — commonly when comparing current vs latest version strings obtained from untrusted sources.

Common situations: Update checkers feeding raw release names/URLs instead of clean version numbers; empty version output from a version command; pre-release or build metadata formats the regex rejects; locale-prefixed strings like "version 1.2.3".

Related errors


AI-assisted analysis of jeessy2/ddns-go@5874c2e666 (2026-09-03). Data as JSON: /api/errors/fee9ba4934cb44cc. Report an issue: GitHub.