hcengineering/platform · error · ApiError
Both width and height must be provided
Error message
Both width and height must be provided
What it means
The viewport parameters are all-or-nothing: if exactly one of `width` or `height` is present in the query string, parsePrintOptions throws this 400 ApiError. A viewport needs both dimensions to be meaningful for the headless browser.
Source
Thrown at services/print/pod-print/src/server.ts:169
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')
}
return { kind, orientation, viewport }
}
export function createServer (
storageConfig: StorageConfiguration,
allowedHostnames: string[]
): { app: Express, close: () => void } {
const storageAdapter = buildStorageFromConfig(storageConfig)
const measureCtx = initStatisticsContext('print', {
factory: () =>
createOpenTelemetryMetricsContext(
'print',
{},
{},
newMetrics(),
new SplitLogger('print', {View on GitHub (pinned to 63e28dc964)
Solutions
- Always send both width and height together, e.g. &width=1280&height=720.
- Or send neither — omit both to use defaults.
- Fix the client URL builder so the two parameters are added as a unit.
- Sanitize empty strings to undefined before deciding whether to append the params.
Example fix
// before
params.set('width', width ?? '') // may yield lone width=
// after
if (width != null && height != null) {
params.set('width', String(width))
params.set('height', String(height))
} Defensive patterns
Strategy: validation
Validate before calling
function appendViewport (params: URLSearchParams, width?: number, height?: number): void {
if ((width == null) !== (height == null)) {
throw new Error('width and height must be provided together')
}
if (width != null && height != null) {
params.set('width', String(width))
params.set('height', String(height))
}
} Try / catch
try {
const res = await fetch(url)
if (!res.ok) {
const body = await res.json()
if (body.code === 400 && /Both width and height/.test(body.message)) {
// either add the missing dimension or drop both and retry
}
throw new Error(body.message)
}
return await res.json()
} catch (err) { /* handle */ } Prevention
- Treat width/height as a single viewport object in client code so they travel together.
- Drop both params when either is missing rather than sending one.
- Add an assertion in your URL builder that viewport params come in pairs.
When it happens
Trigger: GET /print?link=...&width=1280 (height missing), or width= (empty value counts as absent) paired with height=600. Also happens when URL builders drop empty parameters asymmetrically.
Common situations: Copy-pasting an example URL and deleting one parameter; conditional client code that appends width but only conditionally appends height; a serializer that omits undefined height but keeps width.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
- Invalid width or height
- Invalid print kind: ${kind}
- Invalid page orientation: ${orientation}
- Failed to load server config
- getDisplayMedia not supported
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/3d827f29c8521477.
Report an issue: GitHub.