How to fix UnhandledPromiseRejectionWarning: undefined (no error reason provided) in Node.js
This error occurs when a Promise is rejected without passing an error object or reason. Instead of a meaningful error message, Node.js displays "undefined", making debugging extremely difficult.
Quick fix
Fixes UnhandledPromiseRejectionWarning: undefined (no error reason provided)
// Bad - rejecting with undefined
Promise.reject();
Promise.reject(undefined);
reject(); // In promise executor
// Good - reject with Error object
Promise.reject(new Error('Operation failed'));
reject(new Error('Invalid input provided'));
// Also good - reject with meaningful value
Promise.reject('Database connection timeout');
reject({ code: 'INVALID_INPUT', field: 'email' });- Always reject promises with Error objects
- Check async function return paths
- Fix catch blocks that re-reject
- Add global rejection handler for debugging
// Bad - rejecting with undefinedPromise.reject();Promise.reject(undefined);reject(); // In promise executor// Good - reject with Error objectPromise.reject(new Error('Operation failed'));reject(new Error('Invalid input provided'));// Also good - reject with meaningful valuePromise.reject('Database connection timeout');reject({ code: 'INVALID_INPUT', field: 'email' });UnhandledPromiseRejectionWarning: undefined (no error reason provided)
What this error means
The "undefined (no error reason provided)" error appears when Promise.reject() is called without any argument, or when a promise rejection handler doesn't provide a proper error value. This creates a rejection with undefined as the reason, which makes it impossible to understand what went wrong. This is particularly problematic because promises are meant to carry error information through rejection chains. When the rejection reason is undefined, developers lose all context about the failure, making debugging nearly impossible. It's a symptom of poor error handling practices where errors are caught but not properly propagated or where reject() is called without providing meaningful information.
Typical symptoms
- Console shows "UnhandledPromiseRejectionWarning: undefined"
- Error message says "no error reason provided"
- No stack trace or error details available
- Application behavior indicates failure but no clear cause
- Debugging requires adding logging at multiple points
- Error tracking services receive undefined error values
Common causes
- Calling Promise.reject() without passing an error argument
- Throwing undefined in async function or promise executor
- Catch block that re-rejects without an error object
- Function returns undefined instead of rejecting with Error
- Error handler that calls reject() with no parameters
- Async function that implicitly returns undefined on error path
- Third-party library rejecting promises incorrectly
How to fix "UnhandledPromiseRejectionWarning: undefined (no error reason provided)"
Pass a proper Error object when rejecting promises:
// Bad - rejecting with undefined
Promise.reject();
Promise.reject(undefined);
reject(); // In promise executor
// Good - reject with Error object
Promise.reject(new Error('Operation failed'));
reject(new Error('Invalid input provided'));
// Also good - reject with meaningful value
Promise.reject('Database connection timeout');
reject({ code: 'INVALID_INPUT', field: 'email' });Error objects provide stack traces and can carry additional context.
Ensure all error paths in async functions provide error information:
// Bad - implicit undefined return
async function fetchUser(id) {
if (!id) {
throw; // Throws undefined
}
return await db.users.findById(id);
}
// Good - explicit error
async function fetchUser(id) {
if (!id) {
throw new Error('User ID is required');
}
return await db.users.findById(id);
}Ensure catch blocks that re-reject pass the error forward:
// Bad - losing error information
fetch('/api/data')
.catch(err => {
console.error('Fetch failed');
return Promise.reject(); // Rejects with undefined
});
// Good - preserving error
fetch('/api/data')
.catch(err => {
console.error('Fetch failed:', err);
return Promise.reject(err); // Pass error forward
});
// Better - throw to propagate
fetch('/api/data')
.catch(err => {
console.error('Fetch failed:', err);
throw err; // Automatically rejects with err
});Catch undefined rejections to help locate the source:
process.on('unhandledRejection', (reason, promise) => {
if (reason === undefined) {
console.error('⚠️ Promise rejected with undefined!');
console.error('Promise:', promise);
console.error('Stack trace to find source:');
console.error(new Error().stack);
} else {
console.error('Unhandled rejection:', reason);
}
});This helps identify where undefined rejections originate. Run with --trace-warnings for more details.
Check promise executors for incorrect reject calls:
// Bad - reject called without argument
new Promise((resolve, reject) => {
if (someCondition) {
reject(); // Rejects with undefined
}
resolve(result);
});
// Good - reject with error
new Promise((resolve, reject) => {
if (someCondition) {
reject(new Error('Condition not met'));
}
resolve(result);
});
// Better - use try/catch
new Promise((resolve, reject) => {
try {
if (!someCondition) {
throw new Error('Condition not met');
}
resolve(result);
} catch (err) {
reject(err);
}
});Use ESLint rules to catch these issues during development:
// .eslintrc.json
{
"rules": {
"prefer-promise-reject-errors": ["error", {
"allowEmptyReject": false
}],
"@typescript-eslint/no-floating-promises": "error",
"no-throw-literal": "error"
}
}The prefer-promise-reject-errors rule specifically catches Promise.reject() without arguments.
Advanced notes
TypeScript Protection: TypeScript's strict mode can help prevent undefined rejections. Configure tsconfig.json with:
{
"compilerOptions": {
"strict": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
}
}Error Subclassing: Create custom error classes for better error handling:
class ValidationError extends Error {
constructor(message, field) {
super(message);
this.name = 'ValidationError';
this.field = field;
}
}
// Usage
if (!isValid) {
throw new ValidationError('Invalid email format', 'email');
}Debugging with Error.captureStackTrace: For custom rejection reasons, capture stack traces:
function rejectWithTrace(reason) {
const error = new Error(reason);
Error.captureStackTrace(error, rejectWithTrace);
return Promise.reject(error);
}Common Library Patterns: Some libraries (especially older ones) may reject with non-Error values. Wrap them:
async function safeLibraryCall() {
try {
return await thirdPartyLibrary.method();
} catch (err) {
// Normalize undefined or non-Error rejections
if (!err || !(err instanceof Error)) {
throw new Error(`Library error: ${err || 'undefined'}`);
}
throw err;
}
}Promise.all() and undefined: When using Promise.all(), one undefined rejection stops all:
// If any promise rejects with undefined, hard to tell which one
await Promise.all([
operation1(),
operation2(),
operation3()
]);
// Better - add context to each
await Promise.all([
operation1().catch(err => {
throw new Error(`Operation 1 failed: ${err}`);
}),
operation2().catch(err => {
throw new Error(`Operation 2 failed: ${err}`);
}),
operation3().catch(err => {
throw new Error(`Operation 3 failed: ${err}`);
})
]);Performance Note: Creating Error objects is relatively expensive due to stack trace generation. For high-frequency error paths in hot code, consider using plain objects with error information, but always include enough context to debug the issue.
Frequently asked questions
- What does "UnhandledPromiseRejectionWarning: undefined (no error reason provided)" mean?
- reject() is called without any argument, or when a promise rejection handler doesn't provide a proper error value. This creates a rejection with undefined as the reason, which makes it impossible to understand what went wrong. This is particularly problematic because promises are meant to carry error information through rejection chains.
- How do I fix "UnhandledPromiseRejectionWarning: undefined (no error reason provided)"?
- This error occurs when a Promise is rejected without passing an error object or reason. Instead of a meaningful error message, Node.js displays "undefined", making debugging extremely difficult.
- What causes "UnhandledPromiseRejectionWarning: undefined (no error reason provided)"?
- Calling Promise.reject() without passing an error argument Throwing undefined in async function or promise executor Catch block that re-rejects without an error object
- Is the "UnhandledPromiseRejectionWarning: undefined (no error reason provided)" error serious?
- Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.
Official resources & further reading
- 📚Node.js Official Documentation
- 📖MDN: Promise.prototype.catch()(Official Docs)
- 📝
- 📝
- 🐙