langgenius/dify · error · ValidationError
${name} must be an integer when set
Error message
${name} must be an integer when set What it means
Thrown by ensureOptionalInt() in validation.ts:41 as a ValidationError. Optional integer fields (page, limit) may be omitted, but when present must be a safe integer. Floats, numeric strings ('1'), NaN, booleans, and objects all fail Number.isInteger().
Source
Thrown at sdks/nodejs-client/src/client/validation.ts:41
*/
export function ensureOptionalString(value: unknown, name: string): void {
if (value === undefined || value === null) {
return
}
if (typeof value !== 'string' || value.trim().length === 0) {
throw new ValidationError(`${name} must be a non-empty string when set`)
}
if (value.length > MAX_STRING_LENGTH) {
throw new ValidationError(`${name} exceeds maximum length of ${MAX_STRING_LENGTH} characters`)
}
}
export function ensureOptionalInt(value: unknown, name: string): void {
if (value === undefined || value === null) {
return
}
if (!Number.isInteger(value)) {
throw new ValidationError(`${name} must be an integer when set`)
}
}
export function ensureOptionalBoolean(value: unknown, name: string): void {
if (value === undefined || value === null) {
return
}
if (typeof value !== 'boolean') {
throw new ValidationError(`${name} must be a boolean when set`)
}
}
export function ensureStringArray(value: unknown, name: string): void {
if (!Array.isArray(value) || value.length === 0) {
throw new ValidationError(`${name} must be a non-empty string array`)
}
if (value.length > MAX_LIST_LENGTH) {
throw new ValidationError(`${name} exceeds maximum size of ${MAX_LIST_LENGTH} items`)View on GitHub (pinned to ef8544b173)
Solutions
- Coerce at the boundary: const page = rawPage ? Number(rawPage) : undefined; if (!Number.isInteger(page)) ... .
- Use parseInt with radix and validate: const limit = parseInt(rawLimit, 10); pass only if !Number.isNaN(limit).
- Type the upstream options as number | undefined so TypeScript flags string sources.
Example fix
// before
await kb.listDatasets({ page: req.query.page, limit: req.query.limit }) // strings
// after
const page = req.query.page ? Number(req.query.page) : undefined
const limit = req.query.limit ? Number(req.query.limit) : undefined
await kb.listDatasets({ page, limit }) Defensive patterns
Strategy: validation
Validate before calling
function toOptionalInt(value: unknown): number | undefined {
if (value === undefined || value === null) return undefined
const n = Number(value)
if (!Number.isInteger(n)) throw new Error('value must be an integer when set')
return n
} Type guard
function isOptionalInt(value: unknown): value is number | undefined {
return value === undefined || value === null || (typeof value === 'number' && Number.isInteger(value))
} Try / catch
try {
await kb.listDatasets({ page, limit })
} catch (err) {
if (err instanceof Error && /must be an integer when set/.test(err.message)) {
// retry with coerced integers
await kb.listDatasets({ page: page ? Number(page) : undefined, limit: limit ? Number(limit) : undefined })
} else throw err
} Prevention
- Always coerce URL query params to numbers at the handler boundary.
- Type pagination options as number | undefined.
- Reject fractional page values upstream.
When it happens
Trigger: Calling kb.listDatasets({ page: '1', limit: 2 }) (string from query params); { page: 1.5 }; { limit: NaN }; { page: true }. Undefined/null are accepted via early return at validation.ts:37.
Common situations: Reading page/limit from URL query strings (always strings in HTTP) without coercion; parsing JSON config where numbers were quoted; defaulting to 0 or '' and passing through.
Related errors
- ${name} must be a boolean when set
- Parameter '${key}' must be an integer
- expected integer, got ${JSON.stringify(raw)}
- ${name} must be a non-empty string when set
- ${name} exceeds maximum size of ${MAX_LIST_LENGTH} items
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/fefaf4635cc7af21.
Report an issue: GitHub.