{"record":{"id":"fb7d82853243c606","repo":"hcengineering/platform","slug":"document-not-found","errorCode":null,"errorMessage":"Document not found","messagePattern":"Document not found","errorType":"http","errorClass":"ApiError","httpStatus":404,"severity":"error","filePath":"services/print/pod-print/src/server.ts","lineNumber":298,"sourceCode":"      res.send({ id: convertId })\n    })\n  )\n\n  app.get(\n    '/print/:objectClass/:objectId',\n    wrapRequest(async (req, res, wsIds, wsLoginInfo) => {\n      const ctx = req.ctx\n      const objectId = req.params.objectId\n      const objectClass = req.params.objectClass\n      const options = parsePrintOptions(req.query)\n\n      const transactorUrl = wsLoginInfo.endpoint.replace('ws://', 'http://').replace('wss://', 'https://')\n      const client = await createRestTxOperations(transactorUrl, wsLoginInfo.workspace, wsLoginInfo.token)\n\n      try {\n        const doc = await client.findOne(objectClass as Ref<Class<Doc>>, { _id: objectId as Ref<Doc> })\n        if (doc === undefined) {\n          throw new ApiError(404, 'Document not found')\n        }\n\n        const link = await getPublicLink(doc, client, wsIds, true, null)\n\n        const printRes = await ctx.with(\n          'print',\n          { kind: options.kind, orientation: options.orientation },\n          (ctx) => print(ctx, link, options),\n          {\n            link,\n            viewport: options.viewport\n          }\n        )\n\n        if (printRes === undefined) {\n          throw new ApiError(400, 'Failed to print')\n        }\n","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/services/print/pod-print/src/server.ts#L280-L316","documentation":"The /print/:objectClass/:objectId endpoint looks up the document in the workspace via client.findOne using the class and id path parameters. If no document with that _id exists for the given class, it throws this 404 ApiError. The service needs the actual document to generate its public link for printing.","triggerScenarios":"GET /print/:objectClass/:objectId with an objectId that doesn't exist, was deleted, belongs to another workspace, or with an objectClass for which that id is not registered; also malformed/typo'd ids.","commonSituations":"Printing a stale link after the document was deleted; using an id from a different workspace's token; passing the wrong class segment (e.g. document vs task ids swapped); client caching object ids across environment refreshes.","solutions":["Verify the objectId exists by fetching it through the regular API with the same token/class.","Confirm the request token's workspace matches the document's workspace.","Check the objectClass path segment matches the actual class of the object (e.g. 'card:document').","Regenerate the id from the client after document recreation — ids are not stable across re-creation."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"// Verify the object exists (and its class) before calling the print endpoint\nasync function assertDocExists (client: any, objectClass: string, objectId: string): Promise<boolean> {\n  const doc = await client.findOne(objectClass, { _id: objectId })\n  return doc !== undefined\n}\nif (!(await assertDocExists(client, objectClass, objectId))) {\n  throw new Error(`Document ${objectId} does not exist in this workspace`)\n}","typeGuard":"function isFound<T extends { _id: unknown }> (doc: T | undefined): doc is T {\n  return doc !== undefined\n}","tryCatchPattern":"try {\n  const res = await fetch(`/print/${objectClass}/${objectId}`)\n  if (res.status === 404) {\n    const body = await res.json()\n    throw new Error(`Document not available for printing: ${body.message}`)\n  }\n  if (!res.ok) throw new Error((await res.json()).message)\n  return await res.blob()\n} catch (err) { /* handle: refresh stale ids, notify user */ }","preventionTips":["Look up the document with the same class + token before printing.","Never cache object ids across workspace or environment switches.","Handle deletions: remove queued print jobs when the source document is deleted.","Ensure the objectClass path segment is the exact class string, not a mixin or subclass alias."],"tags":["http-404","document-not-found","api","print"],"backgroundTag":"entity-not-found","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}