hcengineering/platform · error · ApiError

Document not found

Error message

Document not found

What it means

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.

Solutions

  1. Verify the objectId exists by fetching it through the regular API with the same token/class.
  2. Confirm the request token's workspace matches the document's workspace.
  3. Check the objectClass path segment matches the actual class of the object (e.g. 'card:document').
  4. Regenerate the id from the client after document recreation — ids are not stable across re-creation.
Defensive patterns

Strategy: type-guard

Validate before calling

// Verify the object exists (and its class) before calling the print endpoint
async function assertDocExists (client: any, objectClass: string, objectId: string): Promise<boolean> {
  const doc = await client.findOne(objectClass, { _id: objectId })
  return doc !== undefined
}
if (!(await assertDocExists(client, objectClass, objectId))) {
  throw new Error(`Document ${objectId} does not exist in this workspace`)
}

Type guard

function isFound<T extends { _id: unknown }> (doc: T | undefined): doc is T {
  return doc !== undefined
}

Try / catch

try {
  const res = await fetch(`/print/${objectClass}/${objectId}`)
  if (res.status === 404) {
    const body = await res.json()
    throw new Error(`Document not available for printing: ${body.message}`)
  }
  if (!res.ok) throw new Error((await res.json()).message)
  return await res.blob()
} catch (err) { /* handle: refresh stale ids, notify user */ }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29). Data as JSON: /api/errors/fb7d82853243c606. Report an issue: GitHub.

Appendix: source

Thrown at services/print/pod-print/src/server.ts:298

      res.send({ id: convertId })
    })
  )

  app.get(
    '/print/:objectClass/:objectId',
    wrapRequest(async (req, res, wsIds, wsLoginInfo) => {
      const ctx = req.ctx
      const objectId = req.params.objectId
      const objectClass = req.params.objectClass
      const options = parsePrintOptions(req.query)

      const transactorUrl = wsLoginInfo.endpoint.replace('ws://', 'http://').replace('wss://', 'https://')
      const client = await createRestTxOperations(transactorUrl, wsLoginInfo.workspace, wsLoginInfo.token)

      try {
        const doc = await client.findOne(objectClass as Ref<Class<Doc>>, { _id: objectId as Ref<Doc> })
        if (doc === undefined) {
          throw new ApiError(404, 'Document not found')
        }

        const link = await getPublicLink(doc, client, wsIds, true, null)

        const printRes = await ctx.with(
          'print',
          { kind: options.kind, orientation: options.orientation },
          (ctx) => print(ctx, link, options),
          {
            link,
            viewport: options.viewport
          }
        )

        if (printRes === undefined) {
          throw new ApiError(400, 'Failed to print')
        }

View on GitHub (pinned to 63e28dc964)