docmirror/dev-sidecar · warning
Invalid version string: ${version}
Error message
Invalid version string: ${version} What it means
parseVersion() parses a version string like 'v1.2.3' or '1.2.3-beta.1' into numeric parts plus a prerelease suffix using a strict regex (^v?digits(\.digits)*[.-]suffix$). If the string does not match — wrong characters, too many dots, empty, or non-version text — this error is thrown. It is thrown inside isNewVersion's try/catch, which converts it to result -999 with a logged error.
Source
Thrown at packages/core/src/utils/util.version.js:4
function parseVersion (version) {
const matched = version.match(/^v?(\d{1,2}(?:\.\d{1,2})*)[.-]?(.*)$/)
if (!matched) {
throw new Error(`Invalid version string: ${version}`)
}
const versionInfo = {
versions: matched[1].split('.'), // 版本号数组
pre: matched[2], // 预发布版本号
}
// 将 versions 中的数字字符串转为数字
for (let i = 0; i < versionInfo.versions.length; i++) {
versionInfo.versions[i] = Number.parseInt(versionInfo.versions[i])
}
return versionInfo
}
/**
* 比较版本号
*
* @param onlineVersion 线上版本号View on GitHub (pinned to 7710cd56cc)
Solutions
- Validate the version string matches /^v?\d+(\.\d+)*([.-].+)?$/ before parsing
- Sanitize what you feed isNewVersion: trim and strip prefixes like 'version ' or build annotations
- If using isNewVersion for update checks, handle its -999 return (comparison failed) rather than letting parseVersion throw
- Fix the source of the version data (e.g. ensure the remote version endpoint returns a bare semver string)
Example fix
// before
const isNew = version.isNewVersion(fetchVersionBody, '1.2.0') // body may be HTML -> parseVersion throws
// after
function isValidVersion (v) { return typeof v === 'string' && /^v?\d{1,2}(\.\d{1,2})*([.-].+)?$/.test(v.trim()) }
const isNew = isValidVersion(fetchVersionBody) ? version.isNewVersion(fetchVersionBody.trim(), '1.2.0') : -999 Defensive patterns
Strategy: validation
Validate before calling
function isValidVersionString(v) {
return typeof v === 'string' && /^v?\d{1,2}(?:\.\d{1,2})*[.-]?[^\s]*$/.test(v.trim())
}
// use only when isValidVersionString(remoteVersion) is true Type guard
function isVersionString(v) { return typeof v === 'string' && /^v?\d{1,2}(?:\.\d{1,2})*([.-].+)?$/.test(v.trim()) } Try / catch
try {
const result = version.isNewVersion(online, current)
} catch (e) {
if (String(e.message).startsWith('Invalid version string')) {
log.error(`Unparseable version: ${e.message}`)
return -999 // treat as 'unknown comparison'
}
throw e
} Prevention
- Trim and sanitize remote version responses before comparing
- Handle isNewVersion's -999 sentinel as a failed comparison
- Ensure version sources return bare semver strings (no HTML/error pages)
- Add a regex pre-check in any code path that feeds dynamic strings to version parsing
When it happens
Trigger: Calling the module's parseVersion (or indirectly isNewVersion) with strings like 'abc', '', '1.2.3.4.5.6...x', 'version 1.2', or a URL/text response mistakenly used as the version; comparing when onlineVersion fetch returned HTML/an error page instead of a version string.
Common situations: Update check against a remote endpoint that returned an error body instead of a version; local package version read from an unexpected source (e.g. malformed package.json); manual version strings with 'v' plus extra text like 'v1.2.3 (build 45)'; empty version variables.
Related errors
AI-assisted analysis of docmirror/dev-sidecar@7710cd56cc (2026-08-31).
Data as JSON: /api/errors/6332b1b4a2b607e9.
Report an issue: GitHub.