overleaf/overleaf · error
ranges are too large
Error message
ranges are too large
What it means
_serializeRanges JSON-stringifies the ranges object and throws a plain Error when the serialized form exceeds MAX_RANGES_SIZE. This prevents unboundedly large track-changes/comment range payloads from being stored in Redis and slowing down every subsequent doc load.
Source
Thrown at services/document-updater/app/js/RedisManager.js:616
// Too late to lock the project
await rclient.del(keys.projectBlock({ project_id: projectId }))
return false
}
return true
},
async unblockProject(projectId) {
const reply = await rclient.del(
keys.projectBlock({ project_id: projectId })
)
const wasBlocked = reply === 1
return wasBlocked
},
_serializeRanges(ranges) {
let jsonRanges = JSON.stringify(ranges)
if (jsonRanges && jsonRanges.length > MAX_RANGES_SIZE) {
throw new Error('ranges are too large')
}
if (jsonRanges === '{}') {
// Most doc will have empty ranges so don't fill redis with lots of '{}' keys
jsonRanges = null
}
return jsonRanges
},
_deserializeRanges(ranges) {
if (ranges == null || ranges === '') {
return {}
} else {
return JSON.parse(ranges)
}
},
_computeHash(docLines) {
// use sha1 checksum of doclines to detect data corruption.View on GitHub (pinned to 28ad3b03b7)
Solutions
- Accept/reject and delete old track-changes to shrink the ranges payload
- Resolve or remove stale comments in the document
- Raise MAX_RANGES_SIZE in RedisManager if legitimate workloads need more room
- Periodically compact/prune ranges via the track-changes service
- Archive very old documents and start fresh copies
Example fix
// before: letting ranges grow unbounded
await applyRangesUpdate(projectId, docId, incomingRanges)
// after: pre-trim ranges before pushing
function pruneRanges(ranges, maxSize = 1000) {
const trimmed = {
comments: (ranges.comments || []).slice(-maxSize),
changes: (ranges.changes || []).slice(-maxSize),
}
if (JSON.stringify(trimmed).length > MAX_RANGES_SIZE) throw new Error('ranges too large after pruning')
return trimmed
}
await applyRangesUpdate(projectId, docId, pruneRanges(ranges)) Defensive patterns
Strategy: validation
Validate before calling
const jsonRanges = JSON.stringify(ranges)
if (jsonRanges && jsonRanges.length > MAX_RANGES_SIZE) {
throw new Error(`ranges payload too large: ${jsonRanges.length} > ${MAX_RANGES_SIZE}`)
} Try / catch
try {
const jsonRanges = RedisManager._serializeRanges(ranges)
// proceed
} catch (err) {
if (err.message === 'ranges are too large') {
await pruneStaleRanges(projectId, docId) // accept/delete old track-changes, then retry
} else {
throw err
}
} Prevention
- Periodically accept/reject track-changes and resolve comments
- Monitor serialized ranges size per doc and alert near the limit
- Size MAX_RANGES_SIZE to your heaviest legitimate documents
- Archive long-lived docs to keep range history compact
When it happens
Trigger: Calling updateDocument (which calls _serializeRanges) or _serializeRanges directly with a ranges object whose JSON representation is larger than MAX_RANGES_SIZE bytes.
Common situations: Very long-lived docs accumulating thousands of track-changes entries; comments never resolved/accepted over years of editing; an overly small MAX_RANGES_SIZE configured for a heavy-collaboration workflow.
Related errors
- null bytes found in ranges
- doc would become too large if appending this text
- comment not found
- blocking resync doc content insert into project history queu
- blocking doc insert into redis: doc is too large
AI-assisted analysis of overleaf/overleaf@28ad3b03b7 (2026-09-03).
Data as JSON: /api/errors/f39853b5c8f2cd25.
Report an issue: GitHub.