hcengineering/platform · error · ApiError
Invalid includeAttachments. Must be boolean
Error message
Invalid includeAttachments. Must be boolean
What it means
The pod-export server validates the optional `includeAttachments` parameter must be a boolean when supplied. This HTTP 400 error is thrown when the value is present but not of boolean type, protecting the export handler from coercible-but-wrong types.
Source
Thrown at services/export/pod-export/src/server.ts:504
includeChildren?: boolean
} = req.body
// Validate required parameters
if (targetWorkspace == null || typeof targetWorkspace !== 'string') {
measureCtx.warn(`Invalid targetWorkspace parameter: ${String(targetWorkspace)}`)
throw new ApiError(400, 'Missing or invalid required parameter: targetWorkspace')
}
if (_class == null || typeof _class !== 'string') {
measureCtx.warn(`Invalid _class parameter: ${String(_class)}`)
throw new ApiError(400, 'Missing or invalid required parameter: _class')
}
if (conflictStrategy !== undefined && conflictStrategy !== 'skip' && conflictStrategy !== 'duplicate') {
measureCtx.warn(`Invalid conflictStrategy: ${String(conflictStrategy)}`)
throw new ApiError(400, 'Invalid conflictStrategy. Must be "skip" or "duplicate"')
}
if (includeAttachments !== undefined && typeof includeAttachments !== 'boolean') {
measureCtx.warn(`Invalid includeAttachments: ${String(includeAttachments)}`)
throw new ApiError(400, 'Invalid includeAttachments. Must be boolean')
}
decodedToken = decodeToken(token)
if (decodedToken.extra?.readonly !== undefined) {
throw new ApiError(403, 'Forbidden: read-only token')
}
// Get target workspace info
const accountClient = getClient(envConfig.AccountsUrl, token)
const targetWsLoginInfo = await accountClient.getLoginWithWorkspaceInfo()
const targetWsInfo = targetWsLoginInfo.workspaces[targetWorkspace]
if (targetWsInfo === undefined) {
measureCtx.warn(`Target workspace not found or not accessible: ${targetWorkspace}`)
throw new ApiError(404, 'Target workspace not found or not accessible')
}
// Verify user has write access to target workspaceView on GitHub (pinned to 63e28dc964)
Solutions
- Send a real boolean: includeAttachments=true or includeAttachments=false (unquoted, boolean JSON type).
- Coerce before sending in the client: value === 'true' ? true : value === 'false' ? false : undefined.
- Omit the parameter if the default behavior is fine.
Example fix
// before params.includeAttachments = 'true' // after params.includeAttachments = String(raw).toLowerCase() === 'true' ? true : undefined
Defensive patterns
Strategy: validation
Validate before calling
if (includeAttachments !== undefined && typeof includeAttachments !== 'boolean') {
throw new Error('includeAttachments must be a boolean when provided')
} Type guard
function isBooleanOrUndefined(v: unknown): v is boolean | undefined {
return v === undefined || typeof v === 'boolean'
} Try / catch
try {
await exportPod(params)
} catch (err) {
if (err instanceof ApiError && err.status === 400 && /includeAttachments/.test(err.message)) {
console.error('includeAttachments must be a real boolean, not a string/number')
} else throw err
} Prevention
- Coerce query-string values ('true'/'false') to booleans before sending.
- Use boolean JSON types in request bodies, never 0/1 or 'yes'/'no'.
- Type the field as boolean | undefined in the client payload interface.
When it happens
Trigger: Passing includeAttachments='true' (string), 1 (number), 'yes', or any non-boolean value to the export endpoint.
Common situations: Query-string parameters arrive as strings, so callers who take user input straight from a URL or form and forward it verbatim hit this; scripts quoting booleans; JSON bodies using 0/1 instead of true/false.
Related errors
- Invalid conflictStrategy. Must be "skip" or "duplicate"
- Failed to load server config
- getDisplayMedia not supported
- No screen access granted
- response.statusText
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/c6942075a8ee11d5.
Report an issue: GitHub.