transloadit/uppy · error · ValidationError

metadata must be an object

Error message

metadata must be an object

What it means

The optional metadata option must be a plain object when provided; anything else (string, number, array treated loosely, etc.) throws a ValidationError before upload starts.

Source

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

    const method = options.httpMethod.toUpperCase()
    if (method !== 'PUT' && method !== 'POST') {
      throw new ValidationError('unsupported HTTP METHOD specified')
    }
  }

  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

View on GitHub (pinned to 5d4dedd02a)

Solutions

  1. Pass metadata as an object: metadata: { foo: 'bar' }
  2. JSON.parse metadata strings received from clients before constructing Uploader
  3. Omit metadata if none is needed

Example fix

// before
metadata: req.body.metadata // '{"foo":"bar"}'

// after
metadata: typeof req.body.metadata === 'string' ? JSON.parse(req.body.metadata) : req.body.metadata
Defensive patterns

Strategy: type-guard

Validate before calling

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

Type guard

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

Try / catch

null

Prevention

When it happens

Trigger: new Uploader({ metadata: 'string' }) or metadata: 42 — any non-object value.

Common situations: Passing JSON-encoded metadata strings from the client without parsing; Uppy metadata not being forwarded as an object through custom integrations.

Related errors


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