{"record":{"id":"b7890780f346ebff","repo":"clockworklabs/SpacetimeDB","slug":"invalid-version-string-version","errorCode":null,"errorMessage":"Invalid version string: ${version}","messagePattern":"Invalid version string: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"crates/bindings-typescript/src/sdk/version.ts","lineNumber":99,"sourceCode":"    return 0; // versions are equal\n  }\n\n  clone(): SemanticVersion {\n    return new SemanticVersion(\n      this.major,\n      this.minor,\n      this.patch,\n      this.preRelease ? [...this.preRelease] : null,\n      this.buildInfo\n    );\n  }\n\n  static parseVersionString(version: string): SemanticVersion {\n    const regex =\n      /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-([\\da-zA-Z-]+(?:\\.[\\da-zA-Z-]+)*))?(?:\\+([\\da-zA-Z-]+(?:\\.[\\da-zA-Z-]+)*))?$/;\n    const match = version.match(regex);\n    if (!match) {\n      throw new Error(`Invalid version string: ${version}`);\n    }\n\n    const major = parseInt(match[1], 10);\n    const minor = parseInt(match[2], 10);\n    const patch = parseInt(match[3], 10);\n    const preRelease = match[4]\n      ? match[4].split('.').map(id => (isNaN(Number(id)) ? id : Number(id)))\n      : null;\n    const buildInfo = match[5] || null;\n\n    return new SemanticVersion(major, minor, patch, preRelease, buildInfo);\n  }\n}\n\n// The SDK depends on some module information that was not generated before this version.\nexport const _MINIMUM_CLI_VERSION: SemanticVersion = new SemanticVersion(\n  1,\n  4,","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/524b4487d949b61a07d4f39c862d1290259dfd20/crates/bindings-typescript/src/sdk/version.ts#L81-L117","documentation":"SemanticVersion.parseVersionString enforces strict semver: three dot-separated numeric components with no leading zeros (0|[1-9]\\d*), an optional -prerelease and optional +build metadata (dot-separated alphanumeric-hyphen identifiers). Any deviation from that grammar throws with the offending string embedded in the message.","triggerScenarios":"Parsing strings like 'v1.4.0' (v prefix), '1.2' (missing patch), '1.02.3' (leading zero), '1.4.0 beta' (space), or '' (empty). In practice the input is versionInfo.cliVersion from generated module metadata.","commonSituations":"A hand-edited or templated version string in generated bindings; CLI output with a 'v' prefix being fed in; build pipelines stamping versions from git describe or custom schemes into the module metadata.","solutions":["Pass a clean 'MAJOR.MINOR.PATCH' string: strip any 'v' prefix and whitespace first","Validate with a semver regex before calling parseVersionString when the string is external input","Fix the pipeline that stamps versionInfo so it emits canonical semver"],"exampleFix":"// before\nconst v = SemanticVersion.parseVersionString('v1.4.0'); // throws\n\n// after\nconst v = SemanticVersion.parseVersionString('v1.4.0'.replace(/^v/, ''));","handlingStrategy":"type-guard","validationCode":"const clean = raw.trim().replace(/^v/, '');\nif (!isSemverString(clean)) throw new TypeError(`not semver: ${raw}`);\nconst v = SemanticVersion.parseVersionString(clean);","typeGuard":"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-]+)*)?$/;\nfunction isSemverString(s: unknown): s is string {\n  return typeof s === 'string' && SEMVER_RE.test(s);\n}","tryCatchPattern":null,"preventionTips":["Strip 'v' prefixes and whitespace from version strings before parsing","Ensure build pipelines stamp canonical semver (no leading zeros, three components) into module metadata"],"tags":["versioning","semver","validation","typescript"],"backgroundTag":"invalid-semver","analyzedSha":"524b4487d949b61a07d4f39c862d1290259dfd20","analyzedAt":"2026-08-16T23:58:54.611Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}