How to Fix 'state not updating during development' in AutoGen (TypeScript)
What this error means
If you’re seeing state not updating during development in AutoGen TypeScript, the runtime is telling you that your agent state is being read from one place and written to another, or that the object holding state is getting recreated between turns. It usually shows up during local development with hot reload, serverless-style handlers, or when you wire AutoGen into a React/Next.js app and expect stateful behavior across rerenders.
In practice, this is almost always a lifecycle problem, not an AutoGen bug.
The Most Common Cause
The #1 cause is creating a new agent, runtime, or store on every request/render instead of keeping a stable instance alive for the whole conversation.
With AutoGen TS, classes like AssistantAgent, UserProxyAgent, and the runtime/state store need consistent identity. If you instantiate them inside a function that runs repeatedly, your “state” resets and it looks like updates are ignored.
Broken vs fixed
| Broken pattern | Fixed pattern |
|---|---|
| Recreates agent/runtime every call | Creates once and reuses |
| State lives in function scope | State lives in module scope or app singleton |
| Hot reload wipes conversation memory | Stable store persists across turns |
// ❌ Broken: new agent/runtime created on every request
import { AssistantAgent } from "@autogen/agent";
import { InMemoryStore } from "@autogen/core";
export async function handleMessage(input: string) {
const store = new InMemoryStore();
const agent = new AssistantAgent({
name: "support_agent",
modelClient,
memory: {
store,
},
});
const result = await agent.run(input);
return result;
}
// ✅ Fixed: create stable instances once
import { AssistantAgent } from "@autogen/agent";
import { InMemoryStore } from "@autogen/core";
const store = new InMemoryStore();
const agent = new AssistantAgent({
name: "support_agent",
modelClient,
memory: {
store,
},
});
export async function handleMessage(input: string) {
const result = await agent.run(input);
return result;
}
If you’re using Next.js route handlers or server actions, do the same thing with a module-level singleton. If you’re using multiple users, key the state by session ID instead of creating one global bucket.
Other Possible Causes
1) You are mutating state in place instead of returning a new value
AutoGen workflows often rely on immutable updates. If you mutate nested objects directly, change detection can fail and the dev loop looks stale.
// ❌ Broken
state.messages.push({ role: "user", content: input });
return state;
// ✅ Fixed
return {
...state,
messages: [...state.messages, { role: "user", content: input }],
};
2) Your state reducer is not wired into the runtime
If you define a custom state shape but never attach the reducer or persistence layer, the agent will run but nothing survives between steps.
// ❌ Broken: custom state exists but no reducer/persistence path
const runtime = new SingleThreadedAgentRuntime({
// missing state manager / persistence config
});
// ✅ Fixed: attach the state manager explicitly
const runtime = new SingleThreadedAgentRuntime({
// depending on your setup, wire persistence here
// e.g. stateManager, checkpointing, or store adapter
});
The exact API depends on your AutoGen package version, but the rule stays the same: define state and persistence together.
3) Hot reload is recreating module state
During development, Vite, Next.js, and ts-node-dev can reload modules aggressively. That means your “singleton” may not be singleton enough.
// ❌ Broken in dev if module gets reloaded often
export const agent = new AssistantAgent({ name: "support_agent", modelClient });
// ✅ Safer pattern for dev servers
declare global {
// eslint-disable-next-line no-var
var supportAgent: AssistantAgent | undefined;
}
export const agent =
globalThis.supportAgent ??
(globalThis.supportAgent = new AssistantAgent({
name: "support_agent",
modelClient,
}));
4) You are mixing session IDs or thread IDs
A common mistake is writing updates under one ID and reading them back with another. The logs look fine, but the conversation appears frozen because each turn lands in a different bucket.
// ❌ Broken
await store.set("conversation-123", { step: 1 });
const state = await store.get("conversation-124"); // wrong key
// ✅ Fixed
const sessionId = req.headers.get("x-session-id")!;
await store.set(sessionId, { step: 1 });
const state = await store.get(sessionId);
How to Debug It
- •
Print object identity
- •Log whether your
AssistantAgent,SingleThreadedAgentRuntime, and store are being recreated. - •If you see new instances every request, that’s your bug.
- •Log whether your
- •
Log the session/thread key
- •Confirm reads and writes use the same ID.
- •A mismatch here causes “missing” updates even when persistence works.
- •
Inspect mutation style
- •Search for
.push(), direct property assignment, or nested object edits. - •Replace them with immutable updates and rerun.
- •Search for
- •
Disable hot reload temporarily
- •Run the app in a plain Node process.
- •If the issue disappears, your dev tooling is resetting module scope.
A quick sanity check:
console.log("agent instance", agent);
console.log("runtime instance", runtime);
console.log("session id", sessionId);
console.log("store keys", await store.keys?.());
If those values change unexpectedly between turns, you’ve found the source.
Prevention
- •Keep
AssistantAgent, runtime objects, and stores outside request handlers unless they are explicitly per-request. - •Use immutable updates for any custom conversation state.
- •Treat session IDs as part of your data model; never hardcode them during development.
- •Add a small integration test that sends two messages in sequence and asserts that turn two sees turn one’s state.
If you build with those rules from day one, this class of bug disappears fast. The failure mode is boring once you know it: unstable lifecycle plus inconsistent storage keying.
Keep learning
- •The complete AI Agents Roadmap — my full 8-step breakdown
- •Free: The AI Agent Starter Kit — PDF checklist + starter code
- •Work with me — I build AI for banks and insurance companies
By Cyprian Aarons, AI Consultant at Topiax.
Want the complete 8-step roadmap?
Grab the free AI Agent Starter Kit — architecture templates, compliance checklists, and a 7-email deep-dive course.
Get the Starter Kit