clockworklabs/SpacetimeDB · error · Error

Invalid version string: ${version}

Error message

Invalid version string: ${version}

What it means

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.

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 524b4487d9)

Solutions

  1. Pass a clean 'MAJOR.MINOR.PATCH' string: strip any 'v' prefix and whitespace first
  2. Validate with a semver regex before calling parseVersionString when the string is external input
  3. Fix the pipeline that stamps versionInfo so it emits canonical semver

Example fix

// before
const v = SemanticVersion.parseVersionString('v1.4.0'); // throws

// after
const v = SemanticVersion.parseVersionString('v1.4.0'.replace(/^v/, ''));
Defensive patterns

Strategy: type-guard

Validate before calling

const clean = raw.trim().replace(/^v/, '');
if (!isSemverString(clean)) throw new TypeError(`not semver: ${raw}`);
const v = SemanticVersion.parseVersionString(clean);

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);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16). Data as JSON: /api/errors/b7890780f346ebff. Report an issue: GitHub.