hcengineering/platform · error · ApiError
Failed to print
Error message
Failed to print
What it means
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.
Source
Thrown at services/print/pod-print/src/server.ts:230
) {
ctx.error('Rejected processing unexpected link', { link })
throw new ApiError(403, 'Cannot process provided link')
}
const options = parsePrintOptions(req.query)
const printRes = await ctx.with(
'print',
{ kind: options.kind, orientation: options.orientation },
(ctx) => print(ctx, link, options),
{
url,
viewport: options.viewport
}
)
if (printRes === undefined) {
throw new ApiError(400, 'Failed to print')
}
const printId = `print-${generateId()}`
await storageAdapter.put(ctx, wsIds, printId, printRes, `application/${options.kind}`, printRes.length)
res.contentType('application/json')
res.send({ id: printId })
})
)
app.get(
'/convert/:file',
wrapRequest(async (req, res, wsUuid) => {
const convertableFormats = ['application/vnd.openxmlformats-officedocument.wordprocessingml.document']
const ctx = req.ctx
const file = req.params.file
const stat = await storageAdapter.stat(ctx, wsUuid, file)View on GitHub (pinned to 63e28dc964)
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.
Defensive patterns
Strategy: retry
Validate before calling
// Pre-check reachability from the same network as the print pod
async function isReachable (url: string): Promise<boolean> {
try { const r = await fetch(url, { method: 'HEAD' }); return r.ok } catch { return false }
}
if (!(await isReachable(targetUrl))) throw new Error(`Target not reachable by print service: ${targetUrl}`) Try / catch
async function printWithRetry (link: string, attempts = 2): Promise<{ id: string }> {
let lastErr: unknown
for (let i = 0; i < attempts; i++) {
try {
const res = await fetch(`/print?link=${encodeURIComponent(link)}`)
if (res.ok) return await res.json()
const body = await res.json()
if (body.code === 400 && /Failed to print/.test(body.message) && i < attempts - 1) continue
throw new Error(body.message)
} catch (err) { lastErr = err }
}
throw lastErr
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Failed to load server config
- getDisplayMedia not supported
- No screen access granted
- "npm view" returned error code ${npmVersionSpawnResult.statu
- Unable to resolve version ${version} of package ${name}: ${e
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/2a1204d4d2fc04ed.
Report an issue: GitHub.