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
- Use the native `new FormData()` (globalThis.FormData) — drop the `form-data` package import.
- 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.
- 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
- Use `new FormData()` (globalThis.FormData) — drop the `form-data` npm package import.
- Require Node >= 18 (got v15 requires Node >= 22) where FormData is built in.
- If you have a polyfill instance, convert its fields to native FormData before passing.
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.