How to fix Error: AsyncLocalStorage variable not set in this context in Node.js
This error occurs when attempting to access AsyncLocalStorage data outside of an asynchronous context initialized by run() or enterWith(). The store is only available within the callback scope or in operations properly bound to that context.
Quick fix
Fixes Error: AsyncLocalStorage variable not set in this context
const { AsyncLocalStorage } = require("node:async_hooks");
const asyncLocalStorage = new AsyncLocalStorage();
asyncLocalStorage.run(new Map(), () => {
asyncLocalStorage.getStore().set("key", "value");
// Code here has access to the store
console.log(asyncLocalStorage.getStore()); // Returns the Map
});- Wrap code in asyncLocalStorage.run()
- Convert callbacks to Promises with util.promisify()
- Use AsyncResource for custom async operations
- Use enterWith() for middleware patterns
const { AsyncLocalStorage } = require("node:async_hooks");const asyncLocalStorage = new AsyncLocalStorage();asyncLocalStorage.run(new Map(), () => {asyncLocalStorage.getStore().set("key", "value");// Code here has access to the storeconsole.log(asyncLocalStorage.getStore()); // Returns the Map});Error: AsyncLocalStorage variable not set in this context
What this error means
AsyncLocalStorage is Node.js's mechanism for maintaining context-specific data across asynchronous operations. When you call asyncLocalStorage.getStore() outside of a run() or enterWith() context, it returns undefined because no store has been established for the current execution context. This error typically manifests when store operations are attempted in callbacks, Promise chains, or async operations that aren't properly bound to the original context.
Typical symptoms
- asyncLocalStorage.getStore() returns undefined unexpectedly
- Context data accessible in one part of code but not in callbacks
- Variables stored with asyncLocalStorage.run() are lost in async operations
- Error thrown when trying to access properties on undefined store
- Works in synchronous code but fails in Promise chains
Common causes
- Accessing store outside of asyncLocalStorage.run() callback scope
- Using callback-based APIs that don't automatically preserve async context
- Context loss in Promise chains or custom async operations
- Custom thenable implementations that don't properly propagate async context
- Async operations that lose the execution context binding
- Forgetting to wrap async code in asyncLocalStorage.run() or enterWith()
How to fix "Error: AsyncLocalStorage variable not set in this context"
The most common fix is to ensure all code that uses the store is wrapped in asyncLocalStorage.run(). This establishes the async context:
const { AsyncLocalStorage } = require("node:async_hooks");
const asyncLocalStorage = new AsyncLocalStorage();
asyncLocalStorage.run(new Map(), () => {
asyncLocalStorage.getStore().set("key", "value");
// Code here has access to the store
console.log(asyncLocalStorage.getStore()); // Returns the Map
});The first argument to run() is the store object (can be Map, object, etc.), and the second is the callback containing your code.
Callback-based APIs often lose context. Convert them to Promises using util.promisify():
const { promisify } = require("util");
const asyncLocalStorage = new AsyncLocalStorage();
// Instead of passing a callback that loses context:
asyncLocalStorage.run(new Map(), async () => {
// BAD: Context may be lost
// oldCallbackApi((err, result) => {
// asyncLocalStorage.getStore(); // undefined
// });
// GOOD: Use promisify to preserve context
const promisifiedApi = promisify(oldCallbackApi);
const result = await promisifiedApi();
asyncLocalStorage.getStore(); // Returns the store
});For custom async operations that aren't automatically context-aware, use AsyncResource:
const { AsyncResource } = require("node:async_hooks");
const { AsyncLocalStorage } = require("node:async_hooks");
const asyncLocalStorage = new AsyncLocalStorage();
class CustomAsyncOp extends AsyncResource {
constructor(callback) {
super("CustomAsyncOp");
this.callback = callback;
}
run(data) {
// runInAsyncScope preserves the async context
this.runInAsyncScope(this.callback, null, data);
}
}
asyncLocalStorage.run(new Map(), () => {
new CustomAsyncOp(() => {
console.log(asyncLocalStorage.getStore()); // Context preserved
}).run({ some: "data" });
});For middleware or frameworks where you can't wrap the entire request flow, use enterWith():
const { AsyncLocalStorage } = require("node:async_hooks");
const asyncLocalStorage = new AsyncLocalStorage();
// Express middleware example
app.use((req, res, next) => {
const store = new Map();
store.set("userId", req.user.id);
// enterWith sets the store for the current async context
asyncLocalStorage.enterWith(store);
next(); // Store is available in route handlers
});
app.get("/", (req, res) => {
const store = asyncLocalStorage.getStore();
console.log(store.get("userId")); // Works!
});Add logging to identify where context is lost:
const { AsyncLocalStorage } = require("node:async_hooks");
const asyncLocalStorage = new AsyncLocalStorage();
asyncLocalStorage.run(new Map(), async () => {
console.log("1. In run():", asyncLocalStorage.getStore()); // Should exist
setTimeout(() => {
console.log("2. In setTimeout:", asyncLocalStorage.getStore()); // May be lost
}, 0);
await new Promise((resolve) => {
console.log("3. In Promise constructor:", asyncLocalStorage.getStore()); // Should exist
resolve();
});
console.log("4. After await:", asyncLocalStorage.getStore()); // Should exist
});Run this to pinpoint where the store becomes undefined, then apply the appropriate fix for that operation type.
Advanced notes
AsyncLocalStorage is designed to work with native Promises and async/await. Some frameworks or libraries with custom Promise implementations may not properly propagate context. In these cases, you may need to manually manage context using AsyncResource or by wrapping operations. Also note that setTimeout, setInterval, and other timer-based APIs do not automatically preserve AsyncLocalStorage context—they execute in a new context. For timer-based operations, either use enterWith() before the timer, or restructure to use async/await with native Promises. When working with worker threads or child processes, each thread has its own AsyncLocalStorage instance; context is not automatically shared across process boundaries.
Frequently asked questions
- What does "Error: AsyncLocalStorage variable not set in this context" mean?
- js's mechanism for maintaining context-specific data across asynchronous operations. getStore() outside of a run() or enterWith() context, it returns undefined because no store has been established for the current execution context. This error typically manifests when store operations are attempted in callbacks, Promise chains, or async operations that aren't properly bound to the original context.
- How do I fix "Error: AsyncLocalStorage variable not set in this context"?
- This error occurs when attempting to access AsyncLocalStorage data outside of an asynchronous context initialized by run() or enterWith(). The store is only available within the callback scope or in operations properly bound to that context.
- What causes "Error: AsyncLocalStorage variable not set in this context"?
- Accessing store outside of asyncLocalStorage.run() callback scope Using callback-based APIs that don't automatically preserve async context Context loss in Promise chains or custom async operations
- Is the "Error: AsyncLocalStorage variable not set in this context" error serious?
- It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.
Official resources & further reading
- 📚Node.js Official Documentation
- 📖Node.js AsyncLocalStorage Documentation(Official Docs)
- 🐙
- 🐙
- 🐙