langgenius/dify · error · ValidationError

${name} must be a non-empty string

Error message

${name} must be a non-empty string

What it means

Thrown by ensureNonEmptyString() in validation.ts:10 as a ValidationError. This is the SDK's workhorse guard for required string parameters: datasetId, documentId, fileId, messageId, user, name, etc. The value must be a string of length ≥ 1 after trim(); anything else (number, undefined, null, '', ' ') fails.

Source

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

import { ValidationError } from '../errors/dify-error'
import { isRecord } from '../internal/type-guards'

const MAX_STRING_LENGTH = 10000
const MAX_LIST_LENGTH = 1000
const MAX_DICT_LENGTH = 100

export function ensureNonEmptyString(value: unknown, name: string): asserts value is string {
  if (typeof value !== 'string' || value.trim().length === 0) {
    throw new ValidationError(`${name} must be a non-empty string`)
  }
  if (value.length > MAX_STRING_LENGTH) {
    throw new ValidationError(`${name} exceeds maximum length of ${MAX_STRING_LENGTH} characters`)
  }
}

/**
 * Validates optional string fields that must be non-empty when provided.
 * Use this for fields like `name` that are optional but should not be empty strings.
 *
 * For filter parameters that accept empty strings (e.g., `keyword: ""`),
 * use `validateParams` which allows empty strings for optional params.
 */
export function ensureOptionalString(value: unknown, name: string): void {
  if (value === undefined || value === null) {
    return
  }
  if (typeof value !== 'string' || value.trim().length === 0) {

View on GitHub (pinned to ef8544b173)

Solutions

  1. Ensure the value is a non-empty trimmed string at the call site: if (!datasetId?.trim()) throw new Error('datasetId required').
  2. Pull ids from a typed source (route params typed as string, DB rows cast with String(id)) rather than untyped objects.
  3. Default missing user identifiers to a stable non-empty value or fail fast in your handler before reaching the SDK.
  4. For server response fields, read from the documented path (e.g. response.id) rather than guessing.

Example fix

// before
await kb.getDataset(row.datasetId) // row.datasetId is undefined

// after
if (!row.datasetId) throw new Error('datasetId missing on row')
await kb.getDataset(row.datasetId)
Defensive patterns

Strategy: validation

Validate before calling

function requireNonEmptyString(value: unknown, name: string): string {
  if (typeof value !== 'string' || value.trim().length === 0) {
    throw new Error(`${name} is required`)
  }
  return value
}

Type guard

function isNonEmptyString(value: unknown): value is string {
  return typeof value === 'string' && value.trim().length > 0
}

Try / catch

try {
  await kb.getDataset(datasetId)
} catch (err) {
  if (err instanceof Error && err.name === 'ValidationError' && /must be a non-empty string/.test(err.message)) {
    // return 400 to caller with field name extracted
  } else throw err
}

Prevention

When it happens

Trigger: Calling any SDK method with a required identifier that is undefined, empty, whitespace-only, or a non-string type. Examples: client.filePreview('', user); kb.getDataset(undefined); client.messageFeedback(req) where req.user is blank; createDataset({ name: ' ' }).

Common situations: Reading an id from an env var or route param that was not set; copying a payload from logs and dropping a field; passing a numeric id where a string is expected; user identifier loaded from a session that is null.

Related errors


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