langgenius/dify · error · ValidationError

${name} must be a non-empty string array

Error message

${name} must be a non-empty string array

What it means

Thrown by ensureStringArray() in validation.ts:56 as a ValidationError. The value must be a non-empty Array; this guard runs first, before the per-item and length-cap checks. It is used for fields like tagIds on listDatasets.

Source

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

    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 {
  if (value === undefined || value === null) {
    return
  }
  ensureStringArray(value, name)
}

View on GitHub (pinned to ef8544b173)

Solutions

  1. Wrap singles in an array: kb.listDatasets({ tagIds: [tagId] }).
  2. Omit the field or guard upstream: const tagIds = ids.length ? ids : undefined.
  3. Ensure JSON sources decode to arrays even for one element.

Example fix

// before
await kb.listDatasets({ tagIds: singleTagId })

// after
await kb.listDatasets({ tagIds: [singleTagId] })
Defensive patterns

Strategy: validation

Validate before calling

function toNonEmptyStringArray(value: unknown): string[] {
  if (!Array.isArray(value) || value.length === 0) throw new Error('must be a non-empty array')
  return value as string[]
}

Type guard

function isNonEmptyStringArray(value: unknown): value is string[] {
  return Array.isArray(value) && value.length > 0
}

Try / catch

try {
  await kb.listDatasets({ tagIds })
} catch (err) {
  if (err instanceof Error && /non-empty string array/.test(err.message)) {
    // wrap single value or skip
    await kb.listDatasets({ tagIds: [tagIds as string] })
  } else throw err
}

Prevention

When it happens

Trigger: Calling kb.listDatasets({ tagIds: undefined }) after the upstream check at knowledge-base.ts:70 already short-circuits length>0, but if reached directly via ensureStringArray: { tagIds: 'single' } (string not array), { tagIds: [] }, { tagIds: null }, { tagIds: {} }.

Common situations: Passing a single id string instead of an array; mapping a list that produced []; JSON-decoding a missing field into null; sharing one variable across multiple optionals.

Related errors


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