{"record":{"id":"61b04ed344cf9d28","repo":"hcengineering/platform","slug":"invalid-page-orientation-orientation","errorCode":null,"errorMessage":"Invalid page orientation: ${orientation}","messagePattern":"Invalid page orientation: (.+?)","errorType":"validation","errorClass":"ApiError","httpStatus":400,"severity":"error","filePath":"services/print/pod-print/src/server.ts","lineNumber":152,"sourceCode":"    next(err)\n  }\n}\n\nconst wrapRequest = (fn: AsyncRequestHandler) => (req: Request, res: Response, next: NextFunction) => {\n  // eslint-disable-next-line @typescript-eslint/no-floating-promises\n  handleRequest(fn, req, res, next)\n}\n\nfunction parsePrintOptions (query: Request['query']): PrintOptions {\n  const kind = query.kind as PrintOptions['kind']\n  const orientation = query.orientation as PrintOptions['orientation']\n\n  if (kind !== undefined && !validKinds.includes(kind as any)) {\n    throw new ApiError(400, `Invalid print kind: ${kind}`)\n  }\n\n  if (orientation !== undefined && !validPageOrientations.includes(orientation as any)) {\n    throw new ApiError(400, `Invalid page orientation: ${orientation}`)\n  }\n\n  const rawWidth = (query.width ?? '') as string\n  const rawHeight = (query.height ?? '') as string\n\n  let viewport: PrintOptions['viewport'] | undefined\n  if (rawWidth.length > 0 && rawHeight.length > 0) {\n    viewport = {\n      width: parseInt(rawWidth, 10),\n      height: parseInt(rawHeight, 10)\n    }\n\n    if (Number.isNaN(viewport.width) || Number.isNaN(viewport.height)) {\n      throw new ApiError(400, 'Invalid width or height')\n    }\n  } else if (rawWidth.length > 0 || rawHeight.length > 0) {\n    throw new ApiError(400, 'Both width and height must be provided')\n  }","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/services/print/pod-print/src/server.ts#L134-L170","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nfetch(`/print?link=${link}&orientation=LandScape`)\n// after\nfetch(`/print?link=${link}&orientation=${'landscape'.trim().toLowerCase()}`)","handlingStrategy":"validation","validationCode":"const VALID_ORIENTATIONS = ['portrait', 'landscape'] // mirror validPageOrientations from ./print\nconst q = new URLSearchParams()\nif (orientation != null) {\n  const normalized = String(orientation).trim().toLowerCase()\n  if (!VALID_ORIENTATIONS.includes(normalized)) {\n    throw new Error(`orientation must be one of: ${VALID_ORIENTATIONS.join(', ')}`)\n  }\n  q.set('orientation', normalized)\n}","typeGuard":"function isValidOrientation (v: unknown): v is 'portrait' | 'landscape' {\n  return typeof v === 'string' && ['portrait', 'landscape'].includes(v)\n}","tryCatchPattern":"try {\n  const res = await fetch(url)\n  if (!res.ok) {\n    const body = await res.json()\n    if (body.code === 400 && /orientation/i.test(body.message)) {\n      // correct orientation param and retry\n    }\n    throw new Error(body.message)\n  }\n  return await res.json()\n} catch (err) { /* handle */ }","preventionTips":["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."],"tags":["validation","http-400","query-params","print-service"],"backgroundTag":"invalid-parameter-value","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}