overleaf/overleaf · error · Errors.InvalidError
Rollout percentage for variant defined in previous version a
Error message
Rollout percentage for variant defined in previous version as ${JSON.stringify(variant)} cannot be decreased: revert to a previous configuration instead What it means
Thrown by _checkNewVariantsConfiguration when the new configuration lowers a variant's rolloutPercent below its value in the previous version. Rollout percentages may only stay flat or increase; to reduce exposure the operator must revert to an earlier version instead of editing forward.
Source
Thrown at services/web/app/src/Features/SplitTests/SplitTestManager.mjs:464
)
if (totalRolloutPercentage > 100) {
throw new Errors.InvalidError(
`Total variants rollout percentage cannot exceed 100`
)
}
for (const variant of variants) {
const newVariantConfiguration = _.find(newVariantsConfiguration, {
name: variant.name,
})
if (!newVariantConfiguration) {
throw new Errors.InvalidError(
`Variant defined in previous version as ${JSON.stringify(
variant
)} cannot be removed in new configuration: either set it inactive or create a new split test`
)
}
if (newVariantConfiguration.rolloutPercent < variant.rolloutPercent) {
throw new Errors.InvalidError(
`Rollout percentage for variant defined in previous version as ${JSON.stringify(
variant
)} cannot be decreased: revert to a previous configuration instead`
)
}
if (variant.userLimit !== undefined) {
// Existing variant has a user limit - can only increase it
if (
newVariantConfiguration.userLimit !== undefined &&
newVariantConfiguration.userLimit < variant.userLimit
) {
throw new Errors.InvalidError(
`User limit for variant '${variant.name}' cannot be decreased: revert to a previous configuration instead`
)
}
} else {
// Existing variant has no user limit - cannot add one
if (newVariantConfiguration.userLimit !== undefined) {View on GitHub (pinned to 28ad3b03b7)
Solutions
- Use revertToPreviousVersion to return to an earlier configuration instead of decreasing percentages via a new version.
- Keep each variant's rolloutPercent >= its previous value in the new configuration.
- Check current version values via SplitTestUtils.getCurrentVersion(splitTest) before drafting the new config.
- Catch Errors.InvalidError (400) and surface the offending variant and percentages.
Example fix
// before
await manager.createNewVersion(name, userId, [{ name: 'variant', rolloutPercent: 25 }]) // was 50
// after
const cur = SplitTestUtils.getCurrentVersion(splitTest)
await manager.revertToPreviousVersion(name, cur.versionNumber) // revert instead Defensive patterns
Strategy: validation
Validate before calling
const current = SplitTestUtils.getCurrentVersion(splitTest)
for (const v of current.variants) {
const nv = cfg.find(c => c.name === v.name)
if (nv && nv.rolloutPercent < v.rolloutPercent) {
throw new Error(`variant '${v.name}' cannot decrease from ${v.rolloutPercent} to ${nv.rolloutPercent}`)
}
} Try / catch
try {
await manager.createNewVersion(name, userId, cfg)
} catch (err) {
if (err instanceof Errors.InvalidError && err.message.includes('cannot be decreased')) {
// call revertToPreviousVersion instead
} else throw err
} Prevention
- Treat rollout percentages as monotonic non-decreasing
- Use revertToPreviousVersion to reduce exposure
- Compare against current version values before submitting a draft
When it happens
Trigger: Calling createNewVersion where for some variant newVariantConfiguration.rolloutPercent < variant.rolloutPercent from the current version, e.g. lowering a botched 100% rollout back to 25% via a new version.
Common situations: Trying to walk back an over-rolled variant; admin UI drafts based on stale data showing a higher previous percent; automated rebalancing that shrinks one variant to grow another.
Related errors
- Total variants rollout percentage cannot exceed 100
- Labs phase requires exactly one variant
- Gradual rollouts can only have a single variant
- Variant defined in previous version as ${JSON.stringify(vari
- User limit for variant '${variant.name}' cannot be decreased
AI-assisted analysis of overleaf/overleaf@28ad3b03b7 (2026-09-03).
Data as JSON: /api/errors/b677cdef6725a169.
Report an issue: GitHub.