moeru-ai/airi · error

Prerelease sequence overflow for ${stage}: ${sequence} excee

Error message

Prerelease sequence overflow for ${stage}: ${sequence} exceeds limit ${maxSequence}

What it means

After parsing the prerelease tag, encodeNumericVersion computes maxSequence = (multiplier-1) - stageBuckets[stage] (multiplier is 10_000). If the sequence number exceeds that cap, the encoded patch would collide with the next stage bucket, so the encoder refuses to produce an ambiguous version. For alpha (bucket 1000) the limit is 8998.

Source

Thrown at integrations/vscode/vscode-airi/scripts/shared.ts:68

    throw new Error(`Invalid semver: ${version}`)

  const major = Number.parseInt(match.groups.major, 10)
  const minor = Number.parseInt(match.groups.minor, 10)
  const patch = Number.parseInt(match.groups.patch, 10)
  const prerelease = match.groups.pre

  const multiplier = 10_000
  const stageBuckets = {
    alpha: 1_000,
    beta: 2_000,
    rc: 3_000,
    stable: 9_000,
  } as const

  const { stage, sequence } = parsePrerelease(prerelease)
  const maxSequence = (multiplier - 1) - stageBuckets[stage]
  if (sequence > maxSequence) {
    throw new Error(`Prerelease sequence overflow for ${stage}: ${sequence} exceeds limit ${maxSequence}`)
  }
  if (sequence < 0) {
    throw new Error(`Prerelease sequence must be non-negative: ${sequence}`)
  }

  const encodedPatch = (patch * multiplier) + (stageBuckets[stage] ?? stageBuckets.alpha) + sequence
  const encoded = `${major}.${minor}.${encodedPatch}`

  return {
    version: encoded,
    preview: stage !== 'stable',
  }
}

function parsePrerelease(prerelease?: string) {
  if (!prerelease) {
    return { stage: 'stable' as const, sequence: 0 }
  }

View on GitHub (pinned to 27111382b4)

Solutions

  1. Bump the minor or major version to reset the prerelease sequence headroom.
  2. If the sequence is a build counter, reset it when moving past a stage or releasing.
  3. Switch the stage forward (alpha -> beta -> rc) which is the intended progression and frees the lower bucket reuse safely.
  4. Cap the CI counter fed into the prerelease identifier below the computed maxSequence.

Example fix

// before
// 0.8.0-alpha.9500 -> throws Prerelease sequence overflow

// after
// bump minor to reset headroom
// 0.9.0-alpha.1 -> encodes cleanly
// OR advance the stage
// 0.8.0-beta.1 -> encodes cleanly
Defensive patterns

Strategy: validation

Validate before calling

function maxSeqForStage(stage: 'alpha'|'beta'|'rc'|'stable') {
  const buckets = { alpha: 1000, beta: 2000, rc: 3000, stable: 9000 }
  return 9999 - buckets[stage]
}
if (sequence > maxSeqForStage(stage)) {
  throw new Error(`Bump the minor version; ${stage}.${sequence} exceeds the encoder budget`)
}

Try / catch

try {
  return encodeNumericVersion(version)
}
catch (err) {
  if (/overflow/i.test((err as Error).message)) {
    // bump minor and retry with a reset sequence
    return encodeNumericVersion(bumpMinor(version))
  }
  throw err
}

Prevention

When it happens

Trigger: Passing '1.2.3-alpha.9000' or higher; a long-running prerelease cycle (e.g. alpha build 9500); prerelease identifiers generated from a CI counter that grows unbounded within a single minor.

Common situations: CI build counters reset only on minor bumps; an alpha cycle runs far longer than expected; tooling appends a timestamp-derived large number as the sequence.

Related errors


AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12). Data as JSON: /api/errors/334edd1680602eae. Report an issue: GitHub.