moeru-ai/airi · error
Prerelease sequence must be non-negative: ${sequence}
Error message
Prerelease sequence must be non-negative: ${sequence} What it means
encodeNumericVersion rejects a negative prerelease sequence. Because the sequence is parsed from the prerelease string by parsePrerelease, a negative value indicates the parser produced one (e.g. it interpreted a malformed identifier as a negative number, or a code path defaulted to -1).
Source
Thrown at integrations/vscode/vscode-airi/scripts/shared.ts:71
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 }
}
const [stageRaw, sequenceRaw] = prerelease.split('.')
const stage = stageRaw === 'beta' || stageRaw === 'rc' || stageRaw === 'alpha' ? stageRaw : 'alpha'View on GitHub (pinned to 27111382b4)
Solutions
- Sanitize the prerelease identifier before encoding: strip non-numeric suffixes and clamp negatives to 0.
- Fix parsePrerelease so it cannot emit a negative sequence (default to 0 when absent).
- Validate the prerelease tag shape upstream in the release script.
Example fix
// before
const { stage, sequence } = parsePrerelease(prerelease) // may yield -1
// after
const { stage, sequence } = parsePrerelease(prerelease)
const safeSequence = Math.max(0, sequence)
// then use safeSequence in the encodedPatch computation and the overflow check Defensive patterns
Strategy: validation
Validate before calling
function sanitizeSequence(seq: number): number {
if (!Number.isFinite(seq) || seq < 0) return 0
return Math.floor(seq)
} Type guard
function isNonNegativeInt(n: unknown): n is number {
return typeof n === 'number' && Number.isInteger(n) && n >= 0
} Try / catch
try {
return encodeNumericVersion(version)
}
catch (err) {
if (/non-negative/i.test((err as Error).message)) {
// strip malformed prerelease and retry without it
return encodeNumericVersion(version.replace(/-.*$/, ''))
}
throw err
} Prevention
- Make parsePrerelease default to 0 instead of emitting a negative sequence.
- Reject prerelease identifiers like 'alpha.-1' at the source.
- Unit-test parsePrerelease against adversarial inputs.
When it happens
Trigger: A prerelease identifier like 'alpha.-1' or a parser branch that assigns -1 when no numeric segment is present; manual construction of a prerelease object with a negative sequence.
Common situations: parsePrerelease returns sequence 0 for missing identifiers, but a malformed tag (e.g. 'alpha.-5') or an upstream bug yields a negative number; unit tests feed adversarial prerelease strings.
Related errors
- Invalid semver: ${version}
- Prerelease sequence overflow for ${stage}: ${sequence} excee
- Invalid Godot stage scene input payload.
- Godot stage exported binary not found. Expected at: ${join(p
- Workflow error: ${errorBody.slice(0, 200)}
AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12).
Data as JSON: /api/errors/fc6f0060c41899b0.
Report an issue: GitHub.