Node.js Error

TypeError [ERR_INVALID_ARG_TYPE]

error code: ERR_INVALID_ARG_TYPE

Complete reference — what it means, all variants (path, data, chunk, from), and every fix: missing await, undefined env vars, ESM __dirname, npm install failures, React build errors, and proper type guards.

Quick Answer: TypeError [ERR_INVALID_ARG_TYPE] means a Node.js built-in received the wrong JavaScript type — almost always undefined or a Promise where a string was expected. Read the argument name in the error message ("path", "data", "chunk", "from"), add a console.log right before the failing call to see the actual value, then trace it back to a missing env var, a missing await, an undefined __dirname in ESM, or an unserialised object.

What is ERR_INVALID_ARG_TYPE?

ERR_INVALID_ARG_TYPE is a TypeError thrown by Node.js core APIs when a function argument fails the internal type check. Unlike JavaScript's own type errors, this error is generated by Node.js's C++ and JavaScript internals before any operation is attempted — it is a strict guard that prevents incorrect types from reaching native code.

The error message always names the offending argument and states both the expected type and the actual type (or value) that was received. Reading the message carefully tells you exactly what to fix.

Exact error messages you will see:
TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received undefined
TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received an instance of Promise
TypeError [ERR_INVALID_ARG_TYPE]: The "data" argument must be of type string or an instance of Buffer. Received undefined
TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be of type string or an instance of Buffer. Received type number (42)
TypeError [ERR_INVALID_ARG_TYPE]: The "from" argument must be of type string. Received undefined
npm ERR! code ERR_INVALID_ARG_TYPE

Full Stack Trace Example

TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received undefined
    at new NodeError (node:internal/errors:405:5)
    at validateString (node:internal/validators:162:11)
    at Object.readFile (node:fs:448:3)
    at readConfig (/app/src/config.js:12:6)
    at Object.<anonymous> (/app/src/index.js:5:1) {
  code: 'ERR_INVALID_ARG_TYPE'
}

The stack trace pinpoints the exact Node.js internal that validated the argument (validateString), the public API that was called (Object.readFile), and the line in your own code that triggered it (config.js:12). Start debugging at your own code line — that is where the undefined value was passed in.

Common Causes

CauseWhy it happens
Passing undefined to an fs function The path argument is undefined because an environment variable, config property, or function parameter was never set before the fs.readFile() / fs.writeFile() call.
__dirname is undefined in ESM modules __dirname and __filename are CommonJS globals. In ES modules (.mjs files or "type": "module" in package.json) they do not exist, so passing __dirname to path.resolve() or path.join() passes undefined.
Passing undefined to path.resolve() or path.join() Any argument to path.resolve() or path.join() that is undefined triggers the error. Common when an object property used as a path segment does not exist.
Missing return value from async function An async function that should return a path or data string has no return statement, so it implicitly returns undefined. The caller then passes that undefined to a built-in.
Forgot await on an async function Without await, the variable holds a Promise object instead of the resolved string. Node.js built-ins reject a Promise as an invalid type. The error message says Received an instance of Promise.
Passing wrong type to stream.write() or response.end() A number, object, or array was passed instead of a string or Buffer. Common when a JSON object is passed directly without JSON.stringify().
Destructuring from undefined or null const { outputPath } = config silently produces undefined when config itself is undefined, or when the key does not exist in the object.
Environment variable not set process.env.OUTPUT_DIR is undefined when the variable is not defined in the shell, .env file, or CI environment. Passed directly to a path argument without a guard.
npm / build tool config issue The "main" field in package.json is missing or points to a non-existent file, causing npm's internal path resolution to pass undefined to a file system call.
React / Create React App (react-scripts) An outdated react-scripts version passes an undefined path to a webpack or file-system function during build. Upgrading react-scripts resolves it.

Fix 1 – Check the value before passing it

The fastest way to diagnose the error is to log or assert the value immediately before the failing call. This confirms what is actually being passed so you can trace it upstream.

const fs = require('fs');

// Bad: passes undefined to fs.readFile without any check
fs.readFile(config.inputPath, 'utf8', (err, data) => { /* ... */ });

// Good: log the value before the call to see what it actually is
console.log('inputPath =', config.inputPath);
fs.readFile(config.inputPath, 'utf8', (err, data) => { /* ... */ });

// Better: assert it is a string and fail with a descriptive message
const assert = require('assert');
assert.strictEqual(typeof config.inputPath, 'string',
  `config.inputPath must be a string, got ${typeof config.inputPath}: ${config.inputPath}`);
fs.readFile(config.inputPath, 'utf8', (err, data) => { /* ... */ });

Fix 2 – Fix __dirname in ES Modules (ESM)

__dirname and __filename are CommonJS-only globals. When your file uses ES module syntax (import/export) — either with a .mjs extension or with "type": "module" in package.json — these globals are not available. Passing the bare name __dirname to path.resolve() or path.join() passes undefined, triggering ERR_INVALID_ARG_TYPE.

// WRONG – __dirname is not defined in ESM; this passes undefined to path.resolve
// TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received undefined
import path from 'path';
const configPath = path.resolve(__dirname, 'config.json'); // ReferenceError or undefined

// CORRECT – recreate __dirname using import.meta.url
import path from 'path';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname  = path.dirname(__filename);

const configPath = path.resolve(__dirname, 'config.json'); // works correctly
Tip: This ESM __dirname pattern is one of the most common causes of ERR_INVALID_ARG_TYPE in modern Node.js projects that have migrated from CommonJS to ES modules. Whenever you see the error on a path.resolve() or path.join() call, check the module system first.

Fix 3 – Validate environment variables at startup

Environment variables are one of the most common sources of undefined. Rather than letting process.env.X silently propagate through your code, validate all required variables when the application starts and throw a descriptive error immediately.

// config.js – validate env vars at startup, not at the point of use
function requireEnv(name) {
  const value = process.env[name];
  if (typeof value !== 'string' || value.trim() === '') {
    throw new Error(
      `Missing required environment variable: ${name}\n` +
      `Set it in your .env file or shell before starting the application.`
    );
  }
  return value;
}

module.exports = {
  outputDir:   requireEnv('OUTPUT_DIR'),
  databaseUrl: requireEnv('DATABASE_URL'),
  apiKey:      requireEnv('API_KEY'),
};

// index.js – any ERR_INVALID_ARG_TYPE from a missing env var is now caught here
const config = require('./config');
// If OUTPUT_DIR is not set, you get a clear error at startup, not deep in fs code.

Fix 4 – Use nullish coalescing for defaults

When a config value or function argument is optional, use the ?? operator to supply a default instead of letting undefined reach a built-in function. You can also use the logical OR operator (||) for any falsy value.

import path from 'path';
import { fileURLToPath } from 'url';
import fs from 'fs/promises';

const __dirname = path.dirname(fileURLToPath(import.meta.url));

async function writeOutput(data, options = {}) {
  // ?? prevents undefined from reaching built-ins when a config key is omitted
  const filePath = options.outputPath ?? path.resolve(__dirname, 'output.json');
  const encoding = options.encoding   ?? 'utf8';

  // filePath is always a string now
  await fs.writeFile(filePath, JSON.stringify(data, null, 2), encoding);
}

// Also works for path.resolve — guard every segment that could be undefined
const obj = {};
const resolved = path.resolve(obj.basePath || __dirname, 'dist'); // safe fallback

Fix 5 – Fix missing await (Promise passed as string)

When an async function returns a string, forgetting await means the caller receives a Promise instead. Node.js built-ins will reject it as the wrong type. The error message will explicitly say Received an instance of Promise.

const fs = require('fs/promises');

async function getConfigPath() {
  // Simulates async config lookup (database, remote config service, etc.)
  return '/etc/myapp/config.json';
}

// WRONG – missing await: configPath is a Promise, not a string
// TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string.
// Received an instance of Promise
async function loadConfigBad() {
  const configPath = getConfigPath(); // forgot await
  return fs.readFile(configPath, 'utf8');
}

// CORRECT – await the async function to get the resolved string
async function loadConfigGood() {
  const configPath = await getConfigPath(); // resolves to '/etc/myapp/config.json'
  return fs.readFile(configPath, 'utf8');
}
Tip: If you see Received an instance of Promise in the error message, a missing await is almost certainly the cause. Search for the variable assignment and confirm that every async call is properly awaited.

Fix 6 – Serialize objects before writing (data / chunk argument)

When passing data to fs.writeFile(), stream.write(), or response.end(), the value must be a string or a Buffer. Passing a plain JavaScript object, array, or number triggers the "data" argument must be of type string or an instance of Buffer variant.

const fs = require('fs/promises');
const http = require('http');

// WRONG – passing an object to fs.writeFile causes ERR_INVALID_ARG_TYPE
// TypeError [ERR_INVALID_ARG_TYPE]: The "data" argument must be of type string
// or an instance of Buffer, TypedArray, or DataView. Received an instance of Object
const results = { count: 42, items: ['a', 'b'] };
await fs.writeFile('output.json', results); // Error!

// CORRECT – serialize to string first
await fs.writeFile('output.json', JSON.stringify(results, null, 2), 'utf8');

// WRONG – passing a number to stream.write
// TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be of type string
// or an instance of Buffer. Received type number (42)
http.createServer((req, res) => {
  const statusCode = 200;
  res.end(statusCode); // Error!

  // CORRECT – convert to string first
  res.setHeader('Content-Type', 'application/json');
  res.end(JSON.stringify({ status: statusCode }));
}).listen(3000);

Fix 7 – npm ERR! code ERR_INVALID_ARG_TYPE during npm install or run

When the error appears in npm output rather than your own code, the cause is usually a misconfigured package.json, a corrupted npm cache, or an outdated npm version. The "from" argument must be of type string variant specifically appears during npm dependency resolution when a package path cannot be determined.

# Step 1: Check your package.json for a valid "main" field
#   If "main" points to a file that does not exist, npm throws ERR_INVALID_ARG_TYPE internally
grep '"main"' package.json

# Step 2: Clear the npm cache
npm cache clean --force

# Step 3: Delete node_modules and package-lock.json, then reinstall
rm -rf node_modules package-lock.json
npm install

# Step 4: Update npm to the latest version
npm install -g npm@latest
npm --version

# Step 5: If using Node.js engines field, make sure your Node.js version matches
node --version
grep '"node"' package.json
package.json "main" field: If your package.json has a "main" field pointing to a file path that does not exist or is set to null/undefined, npm's internal resolver will pass that non-string value to a file system function and throw ERR_INVALID_ARG_TYPE. Verify the path is correct or remove the field entirely to use the default (index.js).

Fix 8 – React / Create React App build error

In React projects bootstrapped with Create React App, ERR_INVALID_ARG_TYPE during npm start or npm run build is almost always caused by an outdated react-scripts package. An old version may pass an undefined path to webpack's file-system resolver.

# Upgrade react-scripts to the latest version
npm install react-scripts@latest

# If the error persists, clear all caches and reinstall from scratch
rm -rf node_modules package-lock.json
npm install

# For ejected Create React App, check webpackDevServer.config.js
# Look for any path that might be constructed from an undefined variable
grep -n "undefined\|resolve\|join" config/webpackDevServer.config.js

Fix 9 – Type check with typeof (external data / user input)

When accepting values from external sources — user input, API responses, parsed JSON — validate the type explicitly before passing them to Node.js built-ins. Consider using TypeScript to catch these issues at compile time instead of at runtime.

const fs = require('fs/promises');

// Guard against wrong types from external callers
async function readUserFile(filePath) {
  if (typeof filePath !== 'string') {
    throw new TypeError(
      `readUserFile: filePath must be a string, got ${typeof filePath} (${String(filePath)})`
    );
  }

  if (filePath.trim() === '') {
    throw new RangeError('readUserFile: filePath must not be an empty string');
  }

  return fs.readFile(filePath, 'utf8');
}

// TypeScript equivalent – catches ERR_INVALID_ARG_TYPE at compile time
// function readUserFile(filePath: string): Promise<string> {
//   return fs.readFile(filePath, 'utf8');
// }

Debugging Checklist

  1. Read the error message — the argument name ("path", "data", "chunk", "from") tells you exactly which parameter is wrong.
  2. Find the line number in your own code from the stack trace (not the node:internal/ frames) and add a console.log to print the value.
  3. If the value is undefined, trace back to where it was set: config object, environment variable, function return value, or destructured property.
  4. If the value is a Promise object (Received an instance of Promise), add a missing await before the async function call.
  5. If using ES modules and the error is on path.resolve() or path.join(), check whether __dirname is defined — it is not available in ESM. Use fileURLToPath(import.meta.url) instead.
  6. If the value is an object or number being passed to stream.write() or response.end(), wrap it with JSON.stringify() or String().
  7. If the error appears in npm output, check package.json for a broken "main" field, clear the npm cache, and update npm.
  8. Use NODE_DEBUG=fs to trace all file system calls and see what path value is actually being passed at the system level.
# Trace all fs calls to see the exact path argument values Node.js is using
NODE_DEBUG=fs node app.js 2>&1 | head -40
Do not use broad type coercion as a fix: Calling String(value) on everything to suppress the error hides the real problem. If value is undefined, String(undefined) produces the literal string "undefined", which will cause a different error (e.g. ENOENT: no such file or directory 'undefined'). Find why the value is undefined and fix the root cause instead.

Frequently Asked Questions

What is ERR_INVALID_ARG_TYPE in Node.js?

ERR_INVALID_ARG_TYPE is a TypeError thrown by Node.js built-in functions when they receive an argument of the wrong JavaScript type. The most common case is passing undefined to a function that expects a string, such as passing an undefined path to fs.readFile(), fs.writeFile(), or path.resolve(). The error message always names the argument and states both the expected and received types.

How do I fix: The "path" argument must be of type string. Received undefined?

This means the variable you passed as the file path is undefined. Add a console.log right before the failing call to confirm the value, then trace it back to its source:

  • Environment variable not set: process.env.OUTPUT_DIR is undefined when missing from .env or CI settings.
  • Missing config property: Use const p = config.path ?? './default' to provide a fallback.
  • ESM module: __dirname is undefined — use fileURLToPath(import.meta.url).
  • Missing await: Add await before the async call that returns the path.
Why does it say "Received an instance of Promise"?

This is caused by a missing await keyword. Without await, the variable holds an unresolved Promise object instead of the actual string value. Find the assignment and add the missing await:

// Wrong
const configPath = getConfigPath(); // returns Promise, not string

// Correct
const configPath = await getConfigPath(); // resolves to string
How do I fix __dirname causing ERR_INVALID_ARG_TYPE in ESM?

__dirname is not defined in ES modules. Use fileURLToPath from the built-in url module to recreate it:

import { fileURLToPath } from 'url';
import path from 'path';

const __filename = fileURLToPath(import.meta.url);
const __dirname  = path.dirname(__filename);
How do I fix npm ERR! code ERR_INVALID_ARG_TYPE during npm install?

Run these steps in order until the error resolves:

  1. Check package.json — ensure the "main" field points to a file that actually exists.
  2. Clear the npm cache: npm cache clean --force
  3. Delete node_modules and package-lock.json, then run npm install again.
  4. Update npm: npm install -g npm@latest
How do I fix ERR_INVALID_ARG_TYPE in a React / Create React App project?

An outdated react-scripts package is the most common cause in CRA projects. Run:

npm install react-scripts@latest

If that does not fix it, delete node_modules and package-lock.json and run npm install again. For ejected apps, inspect config/webpackDevServer.config.js for any path built from a potentially undefined variable.

Why does "The data argument must be of type string or an instance of Buffer" appear?

This variant is thrown by fs.writeFile(), stream.write(), and similar APIs when you pass an object, array, or number instead of a string or Buffer. Serialize the value first:

// Object → JSON string
await fs.writeFile('out.json', JSON.stringify(data, null, 2), 'utf8');

// Number → string
stream.write(String(count));

// Buffer for binary data
stream.write(Buffer.from(binaryData));

Related Errors