hcengineering/platform · warning · ApiError

Invalid print kind: ${kind}

Error message

Invalid print kind: ${kind}

What it means

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.

Source

Thrown at services/print/pod-print/src/server.ts:148

      url: wsLoginInfo.workspaceUrl
    }
    await fn(req, res, wsIds, wsLoginInfo, next)
  } catch (err: unknown) {
    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')

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Use one of the supported values exactly: pdf, jpeg, png, webp (lowercase)
  2. Fix 'jpg' to 'jpeg' — the most common typo
  3. Validate/normalize the kind parameter in the client before building the print URL
  4. Return the list of valid kinds in the 400 response body to make the error self-explanatory

Example fix

// before
GET /print?kind=jpg&object=<id>
// after
GET /print?kind=jpeg&object=<id> // validKinds: pdf | jpeg | png | webp
Defensive patterns

Strategy: validation

Validate before calling

const validKinds = ['pdf', 'jpeg', 'png', 'webp'] as const
type ExportKind = (typeof validKinds)[number]
function normalizeKind(raw: string | undefined): ExportKind {
  const kind = raw?.trim().toLowerCase()
  if (kind === 'jpg') return 'jpeg' // common alias
  if (validKinds.includes(kind as ExportKind)) return kind as ExportKind
  throw new Error(`Invalid print kind '${raw}'. Valid: ${validKinds.join(', ')}`)
}

Type guard

function isExportKind(v: unknown): v is 'pdf' | 'jpeg' | 'png' | 'webp' {
  return typeof v === 'string' && ['pdf', 'jpeg', 'png', 'webp'].includes(v)
}

Try / catch

try {
  const res = await fetch(`/print?kind=${kind}&orientation=${orientation}`)
  if (res.status === 400) {
    const body = await res.json().catch(() => null)
    throw new Error(`Bad print options: ${body?.message ?? res.statusText}`)
  }
  return res
} catch (err) {
  console.error('Print failed:', (err as Error).message)
  throw err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29). Data as JSON: /api/errors/0703d2228a9facb9. Report an issue: GitHub.