langgenius/dify · error · FileUploadError

FormData is required for audio uploads

Error message

FormData is required for audio uploads

What it means

Thrown by audioToText() in base.ts:205 as a FileUploadError when the first argument does not satisfy isFormData(). The SDK requires a real FormData instance (browser FormData, or a Node FormData-like object exposing append/getHeaders) because the /audio-to-text endpoint consumes multipart/form-data. Passing a plain object, Buffer, ReadStream, or undefined is rejected before any HTTP call is made.

Source

Thrown at sdks/nodejs-client/src/client/base.ts:205

  }

  filePreview(fileId: string, user: string, asAttachment?: boolean): Promise<DifyResponse<Buffer>> {
    ensureNonEmptyString(fileId, 'fileId')
    ensureNonEmptyString(user, 'user')
    return this.http.request<Buffer, 'bytes'>({
      method: 'GET',
      path: `/files/${fileId}/preview`,
      query: {
        user,
        as_attachment: asAttachment ? 'true' : undefined,
      },
      responseType: 'bytes',
    })
  }

  audioToText(form: unknown, user: string): Promise<DifyResponse<JsonObject>> {
    if (!isFormData(form)) {
      throw new FileUploadError('FormData is required for audio uploads')
    }
    ensureNonEmptyString(user, 'user')
    appendUserToFormData(form, user)
    return this.http.request({
      method: 'POST',
      path: '/audio-to-text',
      data: form,
    })
  }

  textToAudio(request: TextToAudioRequest): Promise<DifyResponse<Buffer> | BinaryStream>
  textToAudio(
    text: string,
    user: string,
    streaming?: boolean,
    voice?: string,
  ): Promise<DifyResponse<Buffer> | BinaryStream>
  textToAudio(

View on GitHub (pinned to ef8544b173)

Solutions

  1. Construct an actual FormData, append the audio file under the field name expected by the server (typically 'file'), then pass it: const form = new FormData(); form.append('file', fileBlob, 'audio.mp3'); await client.audioToText(form, user).
  2. On Node < 18, install and import a FormData polyfill (e.g. form-data) so isFormData() recognizes it via getHeaders() or constructor.name === 'FormData'.
  3. Confirm the value is not undefined by building the FormData in the same scope that calls audioToText rather than receiving it from an untyped source.
  4. If reading from disk in Node, convert the buffer to a Blob/File before appending rather than passing the Buffer as the form argument.

Example fix

// before
await client.audioToText({ file: '/tmp/a.mp3' }, user) // object, not FormData

// after
import FormData from 'form-data'
const form = new FormData()
form.append('file', fs.createReadStream('/tmp/a.mp3'), 'a.mp3')
await client.audioToText(form, user)
Defensive patterns

Strategy: type-guard

Validate before calling

import { isFormData } from '@dify-platform/dify-client/src/http/form-data'
function asAudioForm(value: unknown): FormData {
  if (!isFormData(value)) throw new Error('audioToText requires a real FormData instance')
  return value as FormData
}

Type guard

import { isFormData } from '@dify-platform/dify-client/src/http/form-data'
function isUploadableForm(value: unknown): value is FormData {
  return isFormData(value)
}

Try / catch

try {
  await client.audioToText(form, user)
} catch (err) {
  if (err instanceof Error && err.name === 'FileUploadError') {
    // log form construction issue, surface user-facing message
  } else throw err
}

Prevention

When it happens

Trigger: Calling client.audioToText(payload, user) where payload is a JS object literal, a Buffer holding audio bytes, undefined/null, or a form library whose object is not recognized by isFormData() (no getHeaders method and constructor.name !== 'FormData'). The guard at base.ts:204 fails and FileUploadError is thrown synchronously.

Common situations: Migrating from an older SDK that accepted an object with a file path; using form-urlencoded instead of multipart; passing a Node Buffer directly; bundlers shimming FormData incorrectly; Node versions < 18 where global FormData is absent and the caller forgot to import a polyfill.

Related errors


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