Skip to content

/errors/semver/valueerror-is-not-valid-semver-string

ValueError: 1.0 is not valid SemVer string (Python semver)

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash)updated
tool
SemVer
exit code
1
versions
semver (PyPI) 3
os
any

ValueError: 1.0 is not valid SemVer string is raised by the Python semver package (semver.Version.parse()) when the string is not a full Semantic Version: exactly three numbers MAJOR.MINOR.PATCH, with optional -prerelease and +build parts. 1.0, v1.2.3 and 1.2.3 with a trailing space are all rejected. Fix the string, or relax parsing for short forms with optional_minor_and_patch=True.

Reproduce it

bash
cat > check.py <<'EOF'
import semver
for s in ["1.0", "v1.2.3", "1.2.3 ", "1.2.3-rc.1+build.5"]:
    try:
        print(repr(s), "->", semver.Version.parse(s))
    except ValueError as e:
        print(repr(s), "->", f"ValueError: {e}")
print(semver.Version.parse("1.0", optional_minor_and_patch=True))
print(semver.Version.is_valid("v1.2.3"), semver.Version.is_valid("1.2.3"))
EOF
uv run -q --no-project --python 3.13 --with semver==3.0.4 python check.py

Output

'1.0' -> ValueError: 1.0 is not valid SemVer string
'v1.2.3' -> ValueError: v1.2.3 is not valid SemVer string
'1.2.3 ' -> ValueError: 1.2.3  is not valid SemVer string
'1.2.3-rc.1+build.5' -> 1.2.3-rc.1+build.5
1.0.0
False True

optional_minor_and_patch=True fills the missing parts with zeros. It does not accept the v prefix: strip it yourself (s.strip().removeprefix("v")).

SemVer is not PEP 440

Python package versions follow PEP 440, not SemVer: 1.0, 2.0rc1 and 1.4.post2 are valid PEP 440 versions but invalid SemVer. To compare versions of Python packages, use packaging:

python
from packaging.version import Version
Version("2.0rc1") < Version("2.0")   # True

Use semver only for strings that are SemVer by contract, such as npm package versions or tags your project defines as MAJOR.MINOR.PATCH.

Parse git tags safely

python
import semver

def tag_version(tag: str):
    s = tag.strip().removeprefix("v")
    return semver.Version.parse(s) if semver.Version.is_valid(s) else None

Sources