clockworklabs/SpacetimeDB · error · Error
Invalid version string
Error message
Invalid version string: ${version} What it means
SemanticVersion.parseVersionString applies a strict semver regex: MAJOR.MINOR.PATCH in decimal with no leading zeros, an optional -prerelease and optional +build segment built from [0-9A-Za-z-] and dots. Anything else — missing fields, a leading 'v', underscores, surrounding whitespace, 'latest' — throws 'Invalid version string'. It is used on path such as build()'s minimum-version check against the remote module's cliVersion metadata, so malformed generated metadata can also surface it.
Solutions
- Normalize before parsing: v.trim().replace(/^v/, '')
- Validate with a semver regex before calling parseVersionString
- Regenerate bindings when the error comes from cliVersion metadata inside remoteModule.versionInfo
Example fix
// before const v = SemanticVersion.parseVersionString(rawTag); // 'v1.2.3' -> throws // after const v = SemanticVersion.parseVersionString(rawTag.trim().replace(/^v/, ''));
Defensive patterns
Strategy: type-guard
Validate before calling
const SEMVER_RE = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[\da-zA-Z-]+(?:\.[\da-zA-Z-]+)*)?(?:\+[\da-zA-Z-]+(?:\.[\da-zA-Z-]+)*)?$/;
const normalized = raw.trim().replace(/^v/, '');
if (!SEMVER_RE.test(normalized)) {
throw new Error(`not a semver string: ${raw}`);
}
const v = SemanticVersion.parseVersionString(normalized); Type guard
const SEMVER_RE = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[\da-zA-Z-]+(?:\.[\da-zA-Z-]+)*)?(?:\+[\da-zA-Z-]+(?:\.[\da-zA-Z-]+)*)?$/;
function isSemverString(s: unknown): s is string {
return typeof s === 'string' && SEMVER_RE.test(s.trim().replace(/^v/, ''));
} Prevention
- Normalize version strings (trim, strip 'v') before parsing
- Never pass git tags, channel labels, or banner text into parseVersionString
- Regenerate bindings when cliVersion metadata is the malformed source
When it happens
Trigger: SemanticVersion.parseVersionString('v1.2.3'), ('1.2'), ('1.02.0'), ('1.2.3-beta_1'), or a version string with whitespace; also build() throwing because remoteModule.versionInfo.cliVersion is malformed.
Common situations: Parsing git tag output ('v' prefix); versions assembled by string concatenation that drop a component; CLI banner strings with extra text; channel labels like 'latest' or 'main' passed where a semver is expected; stale generated bindings containing a bad cliVersion.
Related errors
- Invalid hex UUID
- Brotli compression is not supported by the runtime. Please…
- Cannot nest router at
- Could not find SpacetimeDB client! Did you forget to add a…
- Could not find SpacetimeDB client! Did you forget to call…
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/b7890780f346ebff.
Report an issue: GitHub.
Appendix: source
Thrown at crates/bindings-typescript/src/sdk/version.ts:99
return 0; // versions are equal
}
clone(): SemanticVersion {
return new SemanticVersion(
this.major,
this.minor,
this.patch,
this.preRelease ? [...this.preRelease] : null,
this.buildInfo
);
}
static parseVersionString(version: string): SemanticVersion {
const regex =
/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([\da-zA-Z-]+(?:\.[\da-zA-Z-]+)*))?(?:\+([\da-zA-Z-]+(?:\.[\da-zA-Z-]+)*))?$/;
const match = version.match(regex);
if (!match) {
throw new Error(`Invalid version string: ${version}`);
}
const major = parseInt(match[1], 10);
const minor = parseInt(match[2], 10);
const patch = parseInt(match[3], 10);
const preRelease = match[4]
? match[4].split('.').map(id => (isNaN(Number(id)) ? id : Number(id)))
: null;
const buildInfo = match[5] || null;
return new SemanticVersion(major, minor, patch, preRelease, buildInfo);
}
}
// The SDK depends on some module information that was not generated before this version.
export const _MINIMUM_CLI_VERSION: SemanticVersion = new SemanticVersion(
1,
4,View on GitHub (pinned to 6dee26c6ef)