langgenius/dify · error · NoAudioUploadedError

no_audio_uploaded

no_audio_uploaded

Error message

Please upload your audio.

What it means

HTTP 400 with error_code `no_audio_uploaded`, raised by NoAudioUploadedError when AudioService.transcript_asr raises NoAudioUploadedServiceError. The multipart request did not include an audio file under the expected field. The controller reads `request.files.get("file")` and the service validates it; absence yields this error before any provider call.

Source

Thrown at api/controllers/console/explore/trial.py:684

        try:
            # Get IDs before they might be detached from session
            app_id = app_model.id
            user_id = current_user.id

            response = AudioService.transcript_asr(
                app_model=app_model,
                file=file,
                session=db.session(),
                end_user=None,
            )
            RecommendedAppService.add_trial_app_record(app_id, user_id, session=db.session())
            return response
        except services.errors.app_model_config.AppModelConfigBrokenError:
            logger.exception("App model config broken.")
            raise AppUnavailableError()
        except NoAudioUploadedServiceError:
            raise NoAudioUploadedError()
        except AudioTooLargeServiceError as e:
            raise AudioTooLargeError(str(e))
        except UnsupportedAudioTypeServiceError:
            raise UnsupportedAudioTypeError()
        except ProviderNotSupportSpeechToTextServiceError:
            raise ProviderNotSupportSpeechToTextError()
        except SpeechToTextDisabledServiceError:
            raise SpeechToTextDisabledError()
        except ProviderTokenNotInitError as ex:
            raise ProviderNotInitializeError(ex.description)
        except QuotaExceededError:
            raise ProviderQuotaExceededError()
        except ModelCurrentlyNotSupportError:
            raise ProviderModelCurrentlyNotSupportError()
        except InvokeError as e:
            raise CompletionRequestError(e.description)
        except ValueError as e:
            raise e

View on GitHub (pinned to ef8544b173)

Solutions

  1. Send the audio as multipart/form-data with the field name 'file': `curl -F file=@audio.mp3 <url>`.
  2. On the frontend, confirm the FormData appends under key 'file' and the request Content-Type is multipart (let the browser set the boundary).
  3. Validate the file is non-empty before submitting.

Example fix

// before - sent as JSON
fetch(url, { method: 'POST', body: JSON.stringify({}) })

// after - multipart with field 'file'
const fd = new FormData()
fd.append('file', audioBlob, 'audio.webm')
fetch(url, { method: 'POST', body: fd })
Defensive patterns

Strategy: validation

Validate before calling

if (!(file instanceof Blob && file.size > 0)) {
  throw new Error('attach a non-empty audio file')
}
const fd = new FormData()
fd.append('file', file, file.name || 'audio.webm')

Type guard

function isValidAudioUpload(file: unknown): file is Blob {
  return file instanceof Blob && file.size > 0
}

Try / catch

try {
  const r = await fetch(audioUrl, { method: 'POST', body: fd })
  if (r.status === 400) {
    const body = await r.json()
    if (body.code === 'no_audio_uploaded') promptReattachFile()
  }
} catch (e) { reportToUser(e) }

Prevention

When it happens

Trigger: POST TrialChatAudioApi with a request body that omits the 'file' part, sends it under a different field name, or sends an empty/multipart boundary that Flask did not parse as an upload.

Common situations: Frontend sent JSON instead of multipart/form-data; the file input field name is not exactly 'file'; the browser dropped the attachment on a slow connection; curl invocation forgot -F file=@...

Related errors


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