sindresorhus/got · error · TypeError

Non-native FormData is not supported. Use globalThis.FormDat

Error message

Non-native FormData is not supported. Use globalThis.FormData instead.

What it means

Thrown at source/core/index.ts:946 during body finalization. got only accepts the native platform FormData (`globalThis.FormData`, available in Node 18+) for multipart bodies. The check uses `Object.prototype.toString.call(options.body) === '[object FormData]'` to detect objects that pretend to be FormData (report the same toString tag) but fail the `instanceof FormData` check above. This guards against form-data polyfills (e.g. the older `form-data` package) whose serialization contract differs from the native one and would produce malformed requests.

Source

Thrown at source/core/index.ts:946

			const noContentType = !is.string(headers['content-type']);

			if (isBody) {
				// Native FormData
				if (options.body instanceof FormData) {
					const {body, contentType} = serializeNativeFormDataBody(options.body);
					this._nativeFormDataBody = {
						form: options.body,
						body,
						contentTypeWasGenerated: noContentType,
					};

					if (noContentType) {
						headers['content-type'] = contentType;
					}

					options.body = body;
				} else if (Object.prototype.toString.call(options.body) === '[object FormData]') {
					throw new TypeError('Non-native FormData is not supported. Use globalThis.FormData instead.');
				}
			} else if (isForm) {
				if (noContentType) {
					headers['content-type'] = 'application/x-www-form-urlencoded';
				}

				const {form} = options;
				options.form = undefined;

				options.body = (new URLSearchParams(form)).toString();
			} else {
				if (noContentType) {
					headers['content-type'] = 'application/json';
				}

				const {json} = options;
				options.json = undefined;

View on GitHub (pinned to e3924aa1e5)

Solutions

  1. Use the native `new FormData()` (globalThis.FormData) — drop the `form-data` package import.
  2. If you have an old `form-data` instance, convert it to native FormData by appending each field, or send it as a stream with an explicit content-type header instead.
  3. Upgrade to Node >= 18 (got v15 already requires Node >= 22 per package.json) where globalThis.FormData is built in.

Example fix

// before
import FormData from 'form-data';
const form = new FormData();
form.append('file', fs.createReadStream(path));
await got.post(url, { body: form });

// after — native FormData
const form = new FormData(); // globalThis.FormData
form.append('file', new Blob([fs.readFileSync(path)]), 'file.txt');
await got.post(url, { body: form });
Defensive patterns

Strategy: type-guard

Validate before calling

// Reject polyfilled FormData before calling got.
function assertNativeFormData(body) {
  if (body && Object.prototype.toString.call(body) === '[object FormData]' && !(body instanceof globalThis.FormData)) {
    throw new TypeError('Pass a native globalThis.FormData instance, not a polyfill.');
  }
}
assertNativeFormData(options.body);
await got(url, options);

Type guard

function isNativeFormData(v: unknown): v is FormData {
  return v instanceof globalThis.FormData;
}

function isFormDataImposter(v: unknown): boolean {
  return v !== null && typeof v === 'object'
    && Object.prototype.toString.call(v) === '[object FormData]'
    && !(v instanceof globalThis.FormData);
}

Try / catch

try {
  await got.post(url, { body: form });
} catch (error) {
  if (error instanceof TypeError && /Non-native FormData is not supported/.test(error.message)) {
    // convert polyfill to native FormData, then retry
    throw new Error('Replace the form-data polyfill with globalThis.FormData', { cause: error });
  }
  throw error;
}

Prevention

When it happens

Trigger: Importing the `form-data` npm package and passing its instance as `body`; using a custom class whose `[Symbol.toStringTag]` is 'FormData'; passing a FormData-like object from an older shim that predates globalThis.FormData.

Common situations: Migrating from axios or request which historically used the `form-data` polyfill; copying snippets from older Node tutorials; running on a runtime that doesn't expose globalThis.FormData and shimming it with a non-compliant polyfill.


AI-assisted analysis of sindresorhus/got@e3924aa1e5 (2026-08-03). Data as JSON: /data/errors/e01b51ef6c56221e.json. Report an issue: GitHub.