langgenius/dify · error · ValidationError

Parameter '${key}' must be a string

Error message

Parameter '${key}' must be a string

What it means

Thrown by validateParams() in validation.ts:113 as a ValidationError specifically for the 'user' key. The HTTP layer requires the user identifier (used for audit/end-user attribution on the Dify backend) to be a string. Any non-string user value in query or body fails this key-specific check after the generic size checks.

Source

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

          `Parameter '${key}' exceeds maximum length of ${MAX_STRING_LENGTH} characters`,
        )
      }
    } else if (Array.isArray(value)) {
      if (value.length > MAX_LIST_LENGTH) {
        throw new ValidationError(
          `Parameter '${key}' exceeds maximum size of ${MAX_LIST_LENGTH} items`,
        )
      }
    } else if (isRecord(value)) {
      if (Object.keys(value).length > MAX_DICT_LENGTH) {
        throw new ValidationError(
          `Parameter '${key}' exceeds maximum size of ${MAX_DICT_LENGTH} items`,
        )
      }
    }

    if (key === 'user' && typeof value !== 'string') {
      throw new ValidationError(`Parameter '${key}' must be a string`)
    }
    if ((key === 'page' || key === 'limit' || key === 'page_size') && !Number.isInteger(value)) {
      throw new ValidationError(`Parameter '${key}' must be an integer`)
    }
    if (key === 'files' && !Array.isArray(value) && typeof value !== 'object') {
      throw new ValidationError(`Parameter '${key}' must be a list or dict`)
    }
    if (key === 'rating' && value !== 'like' && value !== 'dislike') {
      throw new ValidationError(`Parameter '${key}' must be 'like' or 'dislike'`)
    }
  })
}

View on GitHub (pinned to ef8544b173)

Solutions

  1. Coerce the user id to string at the boundary: const user = String(internalId).
  2. Pull the identifier field from the user object before passing: session.user.id.
  3. Type the user param as string throughout your call layer so non-strings fail at compile time.

Example fix

// before
await client.chat('fx', { query, user: session.userId }) // session.userId is number 42

// after
await client.chat('fx', { query, user: String(session.userId) })
Defensive patterns

Strategy: type-guard

Validate before calling

function assertUserString(params: Record<string, unknown>) {
  if ('user' in params && typeof params.user !== 'string') {
    throw new Error(`Parameter 'user' must be a string`)
  }
}

Type guard

function isUserString(params: Record<string, unknown>): params is { user: string } {
  return typeof params.user === 'string'
}

Try / catch

try {
  await client.chat('fx', payload)
} catch (err) {
  if (err instanceof Error && /Parameter 'user' must be a string/.test(err.message)) {
    await client.chat('fx', { ...payload, user: String(payload.user) })
  } else throw err
}

Prevention

When it happens

Trigger: Calling any endpoint with { user: 12345 } (numeric id), { user: { id: 1 } } (object), or { user: true } in the query/body. The check at validation.ts:112 fires because key === 'user' && typeof value !== 'string'.

Common situations: Internal user ids stored as numbers in the DB and passed through without coercion; passing a user object instead of its id field; boolean flags accidentally assigned to user.

Related errors


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