How to fix Error: Promise never resolved or rejected (promise pending indefinitely) in Node.js
This error occurs when a Promise remains in a pending state indefinitely because neither resolve() nor reject() is ever called. The code after await never executes, causing operations to hang or the application to appear frozen.
Quick fix
Fixes Error: Promise never resolved or rejected (promise pending indefinitely)
console.log('Before await');
const result = await myPromise();
console.log('After await'); // This line never executes if Promise hangs- Identify the hanging Promise
- Verify Promise is properly settled
- Add timeout protection
- Handle callback-based APIs correctly
console.log('Before await');const result = await myPromise();console.log('After await'); // This line never executes if Promise hangsError: Promise never resolved or rejected (promise pending indefinitely)
What this error means
A Promise in JavaScript has three states: pending, fulfilled, or rejected. When you create a Promise, it starts in the pending state and should eventually transition to either fulfilled (via resolve()) or rejected (via reject()). This error indicates that a Promise has been created but the code inside the Promise executor never calls resolve() or reject(), leaving it perpetually pending. When you await such a Promise, execution halts at that point indefinitely because there's no resolution signal. In Node.js, pending Promises don't keep the process alive by default. If the event loop has no other work to do, Node.js will exit even if Promises are still pending, which can lead to unexpected behavior where your code appears to complete but operations never finish.
Typical symptoms
- Code execution stops at an await statement and never continues
- Functions appear to hang or freeze without error messages
- Node.js process exits prematurely without completing async operations
- API requests or database queries that never return results
- Tests that timeout waiting for async operations to complete
- Application becomes unresponsive with no visible errors in logs
Common causes
- Promise executor function missing resolve() or reject() calls
- Conditional logic that prevents resolve/reject from being reached
- Async operations inside Promise constructor that fail silently
- Third-party library functions that don't properly settle Promises
- Callback-based APIs wrapped in Promises without proper error handling
- Promise.race() or Promise.all() with one or more never-settling Promises
- Event listeners that never fire, preventing Promise resolution
- Network requests without timeout configurations that hang indefinitely
How to fix "Error: Promise never resolved or rejected (promise pending indefinitely)"
Add logging before and after await statements to pinpoint where execution stops:
console.log('Before await');
const result = await myPromise();
console.log('After await'); // This line never executes if Promise hangsCheck your console output to see which await statement is causing the hang.
Ensure your Promise executor calls resolve() or reject():
// BAD: Never calls resolve or reject
const badPromise = new Promise((resolve, reject) => {
const result = someOperation();
// Missing resolve(result) or reject(error)
});
// GOOD: Properly settles the Promise
const goodPromise = new Promise((resolve, reject) => {
try {
const result = someOperation();
resolve(result);
} catch (error) {
reject(error);
}
});Implement a timeout mechanism using Promise.race() to prevent indefinite hanging:
function promiseWithTimeout(promise, timeoutMs = 5000) {
const timeout = new Promise((_, reject) => {
setTimeout(() => {
reject(new Error(`Operation timed out after ${timeoutMs}ms`));
}, timeoutMs);
});
return Promise.race([promise, timeout]);
}
// Usage
try {
const result = await promiseWithTimeout(myPromise(), 5000);
console.log('Success:', result);
} catch (error) {
console.error('Failed or timed out:', error.message);
}When wrapping callback-based functions in Promises, ensure all code paths call resolve/reject:
// BAD: Only resolves on success, never rejects
const badWrapper = new Promise((resolve) => {
fs.readFile('file.txt', (err, data) => {
if (!err) {
resolve(data);
}
// Missing reject(err) for error case
});
});
// GOOD: Handles both success and error
const goodWrapper = new Promise((resolve, reject) => {
fs.readFile('file.txt', (err, data) => {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
// BETTER: Use built-in promisified versions
import { readFile } from 'fs/promises';
const data = await readFile('file.txt');Ensure errors inside Promise executors are caught and rejected:
// BAD: Throws error but doesn't reject
const badPromise = new Promise((resolve, reject) => {
throw new Error('Something failed'); // Not caught!
});
// GOOD: Wrap in try-catch
const goodPromise = new Promise((resolve, reject) => {
try {
const result = riskyOperation();
resolve(result);
} catch (error) {
reject(error);
}
});
// BETTER: Use async/await which auto-wraps errors
const betterPromise = (async () => {
const result = await riskyOperation();
return result;
})();Always add .catch() handlers or try-catch blocks to detect rejections:
// Unhandled rejection (may be silent)
myPromise();
// With error handling
myPromise()
.catch(err => console.error('Promise rejected:', err));
// Or with async/await
try {
await myPromise();
} catch (err) {
console.error('Promise rejected:', err);
}Also add a global handler to catch any unhandled rejections:
process.on('unhandledRejection', (reason, promise) => {
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
});Advanced notes
Debugging Pending Promises: Use Chrome DevTools or VS Code debugger with async stack traces enabled to trace Promise chains. The --trace-warnings flag in Node.js can help identify problematic Promises: node --trace-warnings app.js.
Promise.race() Gotcha: In Promise.race(), if all Promises hang, the race itself hangs. Always include at least one timeout Promise in race scenarios.
Event Loop Behavior: Unlike browsers, Node.js will exit if the event loop has no pending timers or I/O operations, even if Promises are pending. This can mask the issue in production. Use tools like why-is-node-running to diagnose unexpected exits.
Testing Considerations: When writing tests, use test framework timeout configurations (Jest's timeout option, Mocha's this.timeout()) to catch hanging Promises early. Consider using libraries like p-timeout for consistent timeout handling across your codebase.
AbortController Pattern: For fetch requests and other abortable operations, use AbortController with timeouts to properly cancel operations rather than leaving them hanging:
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000);
try {
const response = await fetch(url, { signal: controller.signal });
clearTimeout(timeoutId);
return response;
} catch (error) {
if (error.name === 'AbortError') {
console.log('Request timed out');
}
throw error;
}Frequently asked questions
- What does "Error: Promise never resolved or rejected (promise pending indefinitel" mean?
- A Promise in JavaScript has three states: pending, fulfilled, or rejected. When you create a Promise, it starts in the pending state and should eventually transition to either fulfilled (via resolve()) or rejected (via reject()). This error indicates that a Promise has been created but the code inside the Promise executor never calls resolve() or reject(), leaving it perpetually pending.
- How do I fix "Error: Promise never resolved or rejected (promise pending indefinitel"?
- This error occurs when a Promise remains in a pending state indefinitely because neither resolve() nor reject() is ever called. The code after await never executes, causing operations to hang or the application to appear frozen.
- What causes "Error: Promise never resolved or rejected (promise pending indefinitel"?
- Promise executor function missing resolve() or reject() calls Conditional logic that prevents resolve/reject from being reached Async operations inside Promise constructor that fail silently
- Is the "Error: Promise never resolved or rejected (promise pending indefinitel" 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
- ๐
- ๐
- ๐
- ๐