langgenius/dify · error · ValidationError

${name} must be a boolean when set

Error message

${name} must be a boolean when set

What it means

Thrown by ensureOptionalBoolean() in validation.ts:50 as a ValidationError. Optional boolean fields such as includeAll on listDatasets may be omitted, but when present must be a real boolean. Truthy/falsy values like 'true', 0, 1, 'yes' are rejected because typeof !== 'boolean'.

Source

Thrown at sdks/nodejs-client/src/client/validation.ts:50

    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`)
  }
  value.forEach((item) => {
    if (typeof item !== 'string' || item.trim().length === 0) {
      throw new ValidationError(`${name} must contain non-empty strings`)
    }
  })
}

export function ensureOptionalStringArray(value: unknown, name: string): void {

View on GitHub (pinned to ef8544b173)

Solutions

  1. Coerce explicitly: const includeAll = raw === 'true' ? true : raw === 'false' ? false : undefined.
  2. Avoid Boolean(raw) — Boolean('false') is true; parse the literal string instead.
  3. Set the upstream type to boolean | undefined so non-booleans fail at compile time.

Example fix

// before
await kb.listDatasets({ includeAll: process.env.INCLUDE_ALL })

// after
const raw = process.env.INCLUDE_ALL
const includeAll = raw === 'true' ? true : raw === 'false' ? false : undefined
await kb.listDatasets({ includeAll })
Defensive patterns

Strategy: validation

Validate before calling

function toOptionalBoolean(value: unknown): boolean | undefined {
  if (value === undefined || value === null) return undefined
  if (value === true || value === false) return value
  if (value === 'true') return true
  if (value === 'false') return false
  throw new Error('value must be a boolean when set')
}

Type guard

function isOptionalBoolean(value: unknown): value is boolean | undefined {
  return value === undefined || value === null || typeof value === 'boolean'
}

Try / catch

try {
  await kb.listDatasets({ includeAll })
} catch (err) {
  if (err instanceof Error && /must be a boolean when set/.test(err.message)) {
    await kb.listDatasets({ includeAll: String(includeAll) === 'true' })
  } else throw err
}

Prevention

When it happens

Trigger: Calling kb.listDatasets({ includeAll: 'true' }) (string from env or query), { includeAll: 1 }, { includeAll: 'yes' }. Undefined/null accepted via early return at validation.ts:47.

Common situations: Reading includeAll from an env var or HTTP query string (always string); passing 0/1 from a checkbox serializer; coercing through Boolean('false') which yields true.

Related errors


AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12). Data as JSON: /api/errors/268b03f6bdbdab07. Report an issue: GitHub.