{"record":{"id":"1aec2b196927b08f","repo":"overleaf/overleaf","slug":"no-such-doc-docid-in-project-projectid","errorCode":null,"errorMessage":"No such doc: ${docId} in project ${projectId}","messagePattern":"No such doc: (.+?) in project (.+?)","errorType":"http","errorClass":"NotFoundError","httpStatus":404,"severity":"error","filePath":"services/docstore/app/js/DocManager.js","lineNumber":35,"sourceCode":"  /**\n   * @param {string} projectId\n   * @param {string} docId\n   * @param {{inS3: boolean}} filter\n   * @returns {Promise<WithId<Document>>}\n   * @private\n   */\n  async _getDoc(projectId, docId, filter) {\n    if (filter == null) {\n      filter = {}\n    }\n    if (filter.inS3 !== true) {\n      throw new Error('must include inS3 when getting doc')\n    }\n\n    const doc = await MongoManager.findDoc(projectId, docId, filter)\n\n    if (doc == null) {\n      throw new Errors.NotFoundError(\n        `No such doc: ${docId} in project ${projectId}`\n      )\n    }\n\n    if (doc.inS3) {\n      await DocArchive.unarchiveDoc(projectId, docId)\n      return await DocManager._getDoc(projectId, docId, filter)\n    }\n\n    if (filter.ranges) {\n      RangeManager.fixCommentIds(doc)\n    }\n\n    return doc\n  },\n\n  async isDocDeleted(projectId, docId) {\n    const doc = await MongoManager.findDoc(projectId, docId, {","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/overleaf/overleaf/blob/28ad3b03b71cb4311decdcb55c36b33ec10d72db/services/docstore/app/js/DocManager.js#L17-L53","documentation":"NotFoundError thrown by DocManager._getDoc when MongoManager.findDoc returns null — no doc with that docId exists in the given project. The caller (e.g. getDoc/getFullDoc) requires an existing document to read lines and metadata. It is the canonical 'document does not exist' signal of docstore.","triggerScenarios":"getDoc/getFullDoc called with a docId not present in the project's docs collection; typo'd or truncated ObjectId; doc already deleted but still referenced.","commonSituations":"Stale client references after a doc was deleted; race between deletion and read; mismatched projectId/docId pair from a broken URL or sync bug; forgetting inS3 handling is unrelated — null doc alone triggers this.","solutions":["Verify the projectId/docId pair exists (e.g. via getAllDocs) before reading","Treat as 404 upstream and refresh the client's doc list","Re-create or restore the doc if it was deleted unintentionally","Check that the caller passes the correct ObjectId (not a string from another project)"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// verify doc exists before reading\nconst docs = await docstore.getAllDocs(projectId)\nif (!docs.some(d => String(d._id) === String(docId))) return { status: 'missing-doc' }","typeGuard":"function isDocNotFound(e) { return e && e.name === 'NotFoundError' && /No such doc/.test(e.message) }","tryCatchPattern":"try { return await getDoc(projectId, docId) } catch (e) { if (isDocNotFound(e)) return handleMissingDoc(projectId, docId); throw e }","preventionTips":["Keep client doc lists in sync after deletions","Validate ids belong to the project before calls","Handle 404 as a normal state in editor flows","Watch for delete/read races in concurrent workflows"],"tags":["mongodb","not-found","document"],"backgroundTag":"resource-not-found","analyzedSha":"28ad3b03b71cb4311decdcb55c36b33ec10d72db","analyzedAt":"2026-09-03T02:10:22.807Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T07:17:11.731Z"}