hcengineering/platform · error · ApiError
Invalid page orientation: ${orientation}
Error message
Invalid page orientation: ${orientation} What it means
The print service validates the optional `orientation` query parameter against a fixed list of supported values (validPageOrientations). If the client passes an orientation string that is not one of those values, parsePrintOptions throws this 400 ApiError before any printing is attempted. It exists to fail fast on malformed print options rather than pass garbage into the headless print pipeline.
Source
Thrown at services/print/pod-print/src/server.ts:152
next(err)
}
}
const wrapRequest = (fn: AsyncRequestHandler) => (req: Request, res: Response, next: NextFunction) => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
handleRequest(fn, req, res, next)
}
function parsePrintOptions (query: Request['query']): PrintOptions {
const kind = query.kind as PrintOptions['kind']
const orientation = query.orientation as PrintOptions['orientation']
if (kind !== undefined && !validKinds.includes(kind as any)) {
throw new ApiError(400, `Invalid print kind: ${kind}`)
}
if (orientation !== undefined && !validPageOrientations.includes(orientation as any)) {
throw new ApiError(400, `Invalid page orientation: ${orientation}`)
}
const rawWidth = (query.width ?? '') as string
const rawHeight = (query.height ?? '') as string
let viewport: PrintOptions['viewport'] | undefined
if (rawWidth.length > 0 && rawHeight.length > 0) {
viewport = {
width: parseInt(rawWidth, 10),
height: parseInt(rawHeight, 10)
}
if (Number.isNaN(viewport.width) || Number.isNaN(viewport.height)) {
throw new ApiError(400, 'Invalid width or height')
}
} else if (rawWidth.length > 0 || rawHeight.length > 0) {
throw new ApiError(400, 'Both width and height must be provided')
}View on GitHub (pinned to 63e28dc964)
Solutions
- Check the supported values in services/print/pod-print/src/print.ts (validPageOrientations) and send one of them exactly.
- Send orientation omitted entirely if you don't need a non-default orientation (the check only runs when the parameter is present).
- Normalize the value client-side: lowercase and trim before building the query string.
- If the server's allowed list needs new values, extend validPageOrientations in print.ts.
Example fix
// before
fetch(`/print?link=${link}&orientation=LandScape`)
// after
fetch(`/print?link=${link}&orientation=${'landscape'.trim().toLowerCase()}`) Defensive patterns
Strategy: validation
Validate before calling
const VALID_ORIENTATIONS = ['portrait', 'landscape'] // mirror validPageOrientations from ./print
const q = new URLSearchParams()
if (orientation != null) {
const normalized = String(orientation).trim().toLowerCase()
if (!VALID_ORIENTATIONS.includes(normalized)) {
throw new Error(`orientation must be one of: ${VALID_ORIENTATIONS.join(', ')}`)
}
q.set('orientation', normalized)
} Type guard
function isValidOrientation (v: unknown): v is 'portrait' | 'landscape' {
return typeof v === 'string' && ['portrait', 'landscape'].includes(v)
} Try / catch
try {
const res = await fetch(url)
if (!res.ok) {
const body = await res.json()
if (body.code === 400 && /orientation/i.test(body.message)) {
// correct orientation param and retry
}
throw new Error(body.message)
}
return await res.json()
} catch (err) { /* handle */ } Prevention
- Mirror the server's validPageOrientations list in a shared client constant.
- Trim and lowercase orientation before sending.
- Omit the parameter entirely when default orientation is fine.
- Add a unit test asserting every orientation your app sends is in the allowed list.
When it happens
Trigger: Calling GET /print or GET /print/:objectClass/:objectId with `?orientation=` set to anything other than an entry in validPageOrientations (e.g. 'landscape ' with trailing space, 'LandScape' wrong case, or a misspelled value).
Common situations: Clients hardcoding orientation strings from another API's vocabulary; template code building URLs that URL-encodes or appends whitespace; case-sensitivity surprises since the comparison is exact-match against lowercase values.
Related errors
- Invalid print kind: ${kind}
- Invalid width or height
- Both width and height must be provided
- Failed to load server config
- getDisplayMedia not supported
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/61b04ed344cf9d28.
Report an issue: GitHub.