overleaf/overleaf · error · Chunk.VersionNotFoundError
VersionNotFoundError
VersionNotFoundError
Error message
VersionNotFoundError
What it means
loadAtVersion throws Chunk.VersionNotFoundError when the requested version exceeds the newest version reachable in the loaded chunk plus any non-persisted changes. The history loaded from storage does not extend far enough to contain the requested version.
Source
Thrown at services/history-v1/storage/lib/chunk_store/index.js:257
preferNewer: opts.preferNewer,
}
)
const rawHistory = await historyStore.loadRaw(projectId, chunkRecord.id)
const history = History.fromRaw(rawHistory)
const startVersion = chunkRecord.endVersion - history.countChanges()
if (!opts.persistedOnly) {
// Try to extend the chunk with any non-persisted changes that
// follow the chunk's end version.
const nonPersistedChanges = await getChunkExtension(
projectId,
chunkRecord.endVersion
)
history.pushChanges(nonPersistedChanges)
// Check that the changes do actually contain the requested version
if (version > chunkRecord.endVersion + nonPersistedChanges.length) {
throw new Chunk.VersionNotFoundError(projectId, version)
}
}
await lazyLoadHistoryFiles(history, batchBlobStore)
return new Chunk(history, startVersion)
}
/**
* Load the chunk that contains the version that was current at the given
* timestamp, including blob metadata.
*
* @param {string} projectId
* @param {Date} timestamp
* @param {object} [opts]
* @param {boolean} [opts.persistedOnly] - only include persisted changes
*/
async function loadAtTimestamp(projectId, timestamp, opts = {}) {
assert.projectId(projectId, 'bad projectId')View on GitHub (pinned to 28ad3b03b7)
Solutions
- Clamp or validate the requested version against the latest endVersion (from getLatestChunkMetadata) before loading.
- Flush/persist pending changes so non-persisted changes are included, then retry.
- Use loadAtVersion with preferNewer or fall back to the latest available version.
Example fix
// before
const chunk = await chunkStore.loadAtVersion(projectId, requestedVersion)
// after
const latest = await chunkStore.getLatestChunkMetadata(projectId)
if (requestedVersion > latest.endVersion) {
requestedVersion = latest.endVersion // or throw a client-visible 404
}
const chunk = await chunkStore.loadAtVersion(projectId, requestedVersion) Defensive patterns
Strategy: validation
Validate before calling
const latest = await chunkStore.getLatestChunkMetadata(projectId)
if (version < 0 || version > latest.endVersion) {
throw new Error(`version ${version} out of range (latest ${latest.endVersion})`)
} Type guard
function isVersionNotFound(err) {
return err instanceof Chunk.VersionNotFoundError
} Try / catch
try {
return await chunkStore.loadAtVersion(projectId, version)
} catch (err) {
if (!(err instanceof Chunk.VersionNotFoundError)) throw err
return chunkStore.loadAtVersion(projectId, latestEndVersion) // fall back to latest
} Prevention
- Clamp requested versions against getLatestChunkMetadata before loading.
- Persist pending changes before serving historical reads that depend on them.
- Keep client version counters in sync after restores, clones, or rollbacks.
When it happens
Trigger: Calling loadAtVersion(projectId, version) (directly or via chunk/getChangesAtVersion) with a version greater than the latest chunk's endVersion plus the count of pending non-persisted changes, or a version beyond the end of project history.
Common situations: Client requesting a future/stale version number, version counters out of sync after a restore or clone, calling before pending changes were persisted, or off-by-one when computing versions.
Related errors
- NotFoundError
- Chunk does not include since version
- unexpected end version on chunk to be updated
- unexpected start version on chunk to be updated
- chunk update would decrease chunk version
AI-assisted analysis of overleaf/overleaf@28ad3b03b7 (2026-09-03).
Data as JSON: /api/errors/c56288ae99014a64.
Report an issue: GitHub.