{"record":{"id":"0703d2228a9facb9","repo":"hcengineering/platform","slug":"invalid-print-kind-kind","errorCode":null,"errorMessage":"Invalid print kind: ${kind}","messagePattern":"Invalid print kind: (.+?)","errorType":"validation","errorClass":"ApiError","httpStatus":400,"severity":"warning","filePath":"services/print/pod-print/src/server.ts","lineNumber":148,"sourceCode":"      url: wsLoginInfo.workspaceUrl\n    }\n    await fn(req, res, wsIds, wsLoginInfo, next)\n  } catch (err: unknown) {\n    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')","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/services/print/pod-print/src/server.ts#L130-L166","documentation":"parsePrintOptions validates the print endpoint's query parameters against known enumerations. If a 'kind' query parameter is supplied but is not one of validKinds = ['pdf','jpeg','png','webp'] (see src/print.ts:15), it throws ApiError(400, `Invalid print kind: ${kind}`). The check is skipped when kind is undefined, so only explicitly wrong values fail.","triggerScenarios":"GET /print?kind=jpg (should be 'jpeg'), ?kind=PDF (case-sensitive), ?kind=docx, or any unsupported format string; clients guessing format values instead of using the ExportKind union.","commonSituations":"Using 'jpg' instead of 'jpeg'; uppercase values like 'PDF'; passing an old or renamed format after an API change; generating links with free-form format parameters from user input.","solutions":["Use one of the supported values exactly: pdf, jpeg, png, webp (lowercase)","Fix 'jpg' to 'jpeg' — the most common typo","Validate/normalize the kind parameter in the client before building the print URL","Return the list of valid kinds in the 400 response body to make the error self-explanatory"],"exampleFix":"// before\nGET /print?kind=jpg&object=<id>\n// after\nGET /print?kind=jpeg&object=<id> // validKinds: pdf | jpeg | png | webp","handlingStrategy":"validation","validationCode":"const validKinds = ['pdf', 'jpeg', 'png', 'webp'] as const\ntype ExportKind = (typeof validKinds)[number]\nfunction normalizeKind(raw: string | undefined): ExportKind {\n  const kind = raw?.trim().toLowerCase()\n  if (kind === 'jpg') return 'jpeg' // common alias\n  if (validKinds.includes(kind as ExportKind)) return kind as ExportKind\n  throw new Error(`Invalid print kind '${raw}'. Valid: ${validKinds.join(', ')}`)\n}","typeGuard":"function isExportKind(v: unknown): v is 'pdf' | 'jpeg' | 'png' | 'webp' {\n  return typeof v === 'string' && ['pdf', 'jpeg', 'png', 'webp'].includes(v)\n}","tryCatchPattern":"try {\n  const res = await fetch(`/print?kind=${kind}&orientation=${orientation}`)\n  if (res.status === 400) {\n    const body = await res.json().catch(() => null)\n    throw new Error(`Bad print options: ${body?.message ?? res.statusText}`)\n  }\n  return res\n} catch (err) {\n  console.error('Print failed:', (err as Error).message)\n  throw err\n}","preventionTips":["Type the kind parameter as the ExportKind union in client code so invalid values fail at compile time","Normalize user input: lowercase and map 'jpg'→'jpeg' before sending","Document the supported formats in API docs and in the 400 error message","Add a client-side allowlist check before constructing the print URL"],"tags":["http-400","validation","print-service","query-params"],"backgroundTag":"invalid-parameter-value","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}