transloadit/uppy · error · ValidationError

headers must be an object

Error message

headers must be an object

What it means

The optional headers option must be an object when provided; Companion will send these headers with the upload request. Non-object values throw a ValidationError.

Source

Thrown at packages/@uppy/companion/src/server/Uploader.ts:137

  }

  if (exceedsMaxFileSize(options.companionOptions.maxFileSize, options.size)) {
    throw new ValidationError('maxFileSize exceeded')
  }

  // validate fieldname (optional)
  if (options.fieldname != null && typeof options.fieldname !== 'string') {
    throw new ValidationError('fieldname must be a string')
  }

  // validate metadata (optional)
  if (options.metadata != null && typeof options.metadata !== 'object') {
    throw new ValidationError('metadata must be an object')
  }

  // validate headers (optional)
  if (options.headers != null && typeof options.headers !== 'object') {
    throw new ValidationError('headers must be an object')
  }

  // validate protocol (optional)
  if (
    options.protocol &&
    !Object.values(PROTOCOLS).includes(options.protocol)
  ) {
    throw new ValidationError('unsupported protocol specified')
  }

  // s3 uploads don't require upload destination
  // validation, because the destination is determined
  // by the server's s3 config
  if (options.protocol !== PROTOCOLS.s3Multipart) {
    if (!options.endpoint && !options.uploadUrl) {
      throw new ValidationError('no destination specified')
    }

View on GitHub (pinned to 5d4dedd02a)

Solutions

  1. Pass headers as an object: headers: { 'x-custom': 'value' }
  2. Parse header strings/arrays into an object first
  3. Remove double-nesting when forwarding options

Example fix

// before
headers: JSON.stringify({ 'x-custom': 'value' })

// after
headers: { 'x-custom': 'value' }
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof headers === 'string') headers = JSON.parse(headers)

Type guard

const isHeadersObject = (h: unknown): h is Record<string, string> => h == null || (typeof h === 'object' && !Array.isArray(h))

Try / catch

null

Prevention

When it happens

Trigger: new Uploader({ headers: 'Authorization: ...' }) or headers: ['x-a'] — any non-object headers value.

Common situations: Passing serialized header strings from clients; wrapping headers in an extra layer ({ headers: { headers: {...} } }).

Related errors


AI-assisted analysis of transloadit/uppy@5d4dedd02a (2026-08-28). Data as JSON: /api/errors/441ef8bbabf7e94e. Report an issue: GitHub.