{"record":{"id":"2a407a196258cc77","repo":"overleaf/overleaf","slug":"chunk-for-projectid-v-version-not-found","errorCode":null,"errorMessage":"chunk for ${projectId} v ${version} not found","messagePattern":"chunk for (.+?) v (.+?) not found","errorType":"exception","errorClass":"Chunk.VersionNotFoundError","httpStatus":404,"severity":"error","filePath":"services/history-v1/storage/lib/chunk_store/postgres.js","lineNumber":58,"sourceCode":" * Get the metadata for the chunk that contains the given version.\n *\n * @param {string} projectId\n * @param {number} version\n * @param {object} [opts]\n * @param {boolean} [opts.preferNewer] - If the version is at the boundary of\n *        two chunks, return the newer chunk.\n */\nasync function getChunkForVersion(projectId, version, opts = {}) {\n  assert.postgresId(projectId, 'bad projectId')\n\n  const record = await knex('chunks')\n    .where('doc_id', parseInt(projectId, 10))\n    .where('start_version', '<=', version)\n    .where('end_version', '>=', version)\n    .orderBy('end_version', opts.preferNewer ? 'desc' : 'asc')\n    .first()\n  if (!record) {\n    throw new Chunk.VersionNotFoundError(projectId, version)\n  }\n  return chunkFromRecord(record)\n}\n\n/**\n * Get the metadata for the chunk that contains the version that was current at\n * the given timestamp.\n *\n * @param {string} projectId\n * @param {Date} timestamp\n */\nasync function getChunkForTimestamp(projectId, timestamp) {\n  assert.postgresId(projectId, 'bad projectId')\n\n  // This query will find the latest chunk after the timestamp (query orders\n  // in reverse chronological order), OR the latest chunk\n  // This accounts for the case where the timestamp is ahead of the chunk's\n  // timestamp and therefore will not return any results","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/overleaf/overleaf/blob/28ad3b03b71cb4311decdcb55c36b33ec10d72db/services/history-v1/storage/lib/chunk_store/postgres.js#L40-L76","documentation":"In the postgres chunk store, getChunkForVersion throws Chunk.VersionNotFoundError when no row in the chunks table satisfies start_version <= version <= end_version for the given doc_id. The library throws it because the requested version does not exist in the persisted history.","triggerScenarios":"Calling getChunkForVersion(projectId, version) with a version greater than the latest end_version, a version before the first chunk, or a projectId (doc_id) with no chunk rows.","commonSituations":"Version number from a different project; requesting history before a project was flushed to postgres; truncated history after resync; passing a mongo id where a numeric postgres id is required.","solutions":["Query the valid range: SELECT MIN(start_version), MAX(end_version) FROM chunks WHERE doc_id = <id>; clamp or reject out-of-range versions.","Confirm the projectId is the numeric postgres doc id (parseInt must yield the right value).","If rows are missing, re-sync project history into the chunk store.","Check the requested version against the project's current history version counter."],"exampleFix":"// before\nconst chunk = await chunkStore.getChunkForVersion(projectId, 5000) // throws if absent\n// after\nconst range = await knex('chunks').where('doc_id', projectId)\n  .min('start_version as s').max('end_version as e').first()\nif (!range || version < range.s || version > range.e) {\n  return res.status(404).json({error: 'version not found'})\n}\nconst chunk = await chunkStore.getChunkForVersion(projectId, version)","handlingStrategy":"validation","validationCode":"const range = await knex('chunks')\n  .where('doc_id', parseInt(projectId, 10))\n  .min('start_version as minV').max('end_version as maxV').first()\nif (!range || version < Number(range.minV) || version > Number(range.maxV)) {\n  throw new NotFound(`version ${version} outside stored range for ${projectId}`)\n}","typeGuard":"function isVersionStored(range, version) {\n  return range != null && range.minV != null &&\n    version >= range.minV && version <= range.maxV\n}","tryCatchPattern":"try {\n  const chunk = await chunkStore.getChunkForVersion(projectId, version)\n} catch (err) {\n  if (err instanceof Chunk.VersionNotFoundError) {\n    return res.status(404).json({error: 'version not found', projectId, version})\n  }\n  throw err\n}","preventionTips":["Validate the version against the stored min/max range before querying.","Ensure projectId parses to the correct integer doc id.","Trigger history flushes before exposing version endpoints for new projects.","Monitor missing-version requests to detect history resync gaps."],"tags":["postgres","history","not-found","versioning"],"backgroundTag":"chunk-version-not-found","analyzedSha":"28ad3b03b71cb4311decdcb55c36b33ec10d72db","analyzedAt":"2026-09-03T02:10:22.807Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T07:17:11.731Z"}