{"record":{"id":"2a1204d4d2fc04ed","repo":"hcengineering/platform","slug":"failed-to-print","errorCode":null,"errorMessage":"Failed to print","messagePattern":"Failed to print","errorType":"http","errorClass":"ApiError","httpStatus":400,"severity":"error","filePath":"services/print/pod-print/src/server.ts","lineNumber":230,"sourceCode":"      ) {\n        ctx.error('Rejected processing unexpected link', { link })\n        throw new ApiError(403, 'Cannot process provided link')\n      }\n\n      const options = parsePrintOptions(req.query)\n\n      const printRes = await ctx.with(\n        'print',\n        { kind: options.kind, orientation: options.orientation },\n        (ctx) => print(ctx, link, options),\n        {\n          url,\n          viewport: options.viewport\n        }\n      )\n\n      if (printRes === undefined) {\n        throw new ApiError(400, 'Failed to print')\n      }\n\n      const printId = `print-${generateId()}`\n\n      await storageAdapter.put(ctx, wsIds, printId, printRes, `application/${options.kind}`, printRes.length)\n\n      res.contentType('application/json')\n      res.send({ id: printId })\n    })\n  )\n\n  app.get(\n    '/convert/:file',\n    wrapRequest(async (req, res, wsUuid) => {\n      const convertableFormats = ['application/vnd.openxmlformats-officedocument.wordprocessingml.document']\n      const ctx = req.ctx\n      const file = req.params.file\n      const stat = await storageAdapter.stat(ctx, wsUuid, file)","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/services/print/pod-print/src/server.ts#L212-L248","documentation":"The print() step returned undefined, meaning the headless-browser rendering pipeline did not produce a PDF/image buffer for the target URL. The service converts that into this 400 ApiError instead of storing an empty result. The actual root cause (page load failure, crash, timeout) is logged in the service context, not in this message.","triggerScenarios":"GET /print where the target page fails to load or the renderer returns no data — e.g. unreachable URL, page requiring auth/JS that never settles, renderer timeout, or an invalid viewport that makes the render fail.","commonSituations":"Whitelisted-but-internal URLs the print pod cannot actually reach (DNS/network isolation); pages behind login that redirect to an error; very heavy pages exceeding renderer limits; stale whitelisted hostnames after infrastructure changes.","solutions":["Verify the link is reachable from the print pod itself (network/DNS), not just from your machine.","Check the print service logs for the underlying ctx.with('print', ...) failure preceding this error.","Retry once — transient page-load/renderer failures can resolve; ensure your target page loads without authentication.","Simplify the page or supply viewport params; if a specific page consistently fails, reproduce with the same URL in a local headless browser."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Pre-check reachability from the same network as the print pod\nasync function isReachable (url: string): Promise<boolean> {\n  try { const r = await fetch(url, { method: 'HEAD' }); return r.ok } catch { return false }\n}\nif (!(await isReachable(targetUrl))) throw new Error(`Target not reachable by print service: ${targetUrl}`)","typeGuard":null,"tryCatchPattern":"async function printWithRetry (link: string, attempts = 2): Promise<{ id: string }> {\n  let lastErr: unknown\n  for (let i = 0; i < attempts; i++) {\n    try {\n      const res = await fetch(`/print?link=${encodeURIComponent(link)}`)\n      if (res.ok) return await res.json()\n      const body = await res.json()\n      if (body.code === 400 && /Failed to print/.test(body.message) && i < attempts - 1) continue\n      throw new Error(body.message)\n    } catch (err) { lastErr = err }\n  }\n  throw lastErr\n}","preventionTips":["Verify target pages are reachable from the print pod's network, not just your machine.","Avoid printing pages behind authentication or heavy JS that never settles.","Set explicit viewport params when printing pages with odd layouts.","Inspect print-service logs (ctx.with('print')) for the root cause; monitor and alert on renderer failures."],"tags":["print","headless-browser","http-400","network"],"backgroundTag":"render-failed","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}