How to Fix 'callback not firing when scaling' in AutoGen (TypeScript)

By Cyprian AaronsUpdated 2026-04-21
callback-not-firing-when-scalingautogentypescript

When callback not firing when scaling shows up in AutoGen TypeScript, it usually means your agent logic works in a single-process test, but the callback never reaches the worker that actually handles the scaled-out request. In practice, this happens when you move from local execution to multiple instances, queues, or serverless handlers and assume in-memory callbacks will still behave the same.

The root issue is almost always one of two things: the callback was registered on the wrong instance, or the event that should trigger it never makes it across process boundaries.

The Most Common Cause

The #1 cause is registering callbacks on a local AssistantAgent or UserProxyAgent instance, then expecting those callbacks to fire after the request has been routed through another worker, thread, or process.

In AutoGen TypeScript, callbacks are often attached via agent event hooks or runtime handlers. If you create the agent inside a request handler and scale horizontally, each instance has its own memory. The callback registration disappears as soon as the request leaves that process.

Here’s the broken pattern:

BrokenFixed
Callback stored in ephemeral memoryCallback registered on shared runtime / durable handler
// BROKEN: callback lives only in this process
import { AssistantAgent } from "@autogen/core";

export async function handleRequest(req: Request) {
  const agent = new AssistantAgent({
    name: "support-agent",
    modelClient,
  });

  agent.on("message", async (msg) => {
    console.log("Callback fired:", msg.content);
  });

  // Works locally, fails when scaled across workers/instances
  await agent.run("Summarize account activity");
}
// FIXED: register callback in a shared orchestration layer
import { AssistantAgent } from "@autogen/core";

const agent = new AssistantAgent({
  name: "support-agent",
  modelClient,
});

// Register once during app startup, not per request
agent.on("message", async (msg) => {
  console.log("Callback fired:", msg.content);
});

export async function handleRequest(req: Request) {
  await agent.run("Summarize account activity");
}

If you’re using a queue or serverless setup, don’t rely on in-memory listeners at all. Persist state externally and make the callback idempotent.

Other Possible Causes

1. You’re awaiting the wrong method

Some AutoGen flows emit events only during streaming or stepwise execution. If you call a convenience method that returns after completion without streaming hooks enabled, your callback may never fire.

// Wrong: no streaming/event loop attached
await assistant.run("Check policy status");

// Right: use streaming/event-aware execution if supported by your setup
for await (const event of assistant.runStream("Check policy status")) {
  console.log(event);
}

2. Your callback signature does not match the event payload

A mismatched handler can fail silently or throw inside the listener. In TypeScript this often looks fine at compile time if you used any, but at runtime your logic never executes correctly.

// Wrong: assumes payload shape that isn't there
agent.on("message", async ({ text }) => {
  console.log(text.toUpperCase());
});

// Right: inspect actual event shape first
agent.on("message", async (msg) => {
  console.log(msg.content);
});

If you see errors like TypeError: Cannot read properties of undefined, this is usually the culprit.

3. Multiple instances are handling different parts of the flow

With scaling, one worker may register the callback while another worker processes the message. The result is classic: logs show registration happened, but nothing fires later.

// Bad for scaling: registration and execution split across workers
app.post("/start", async () => {
  sharedEmitter.on("done", handler);
});

app.post("/execute", async () => {
  sharedEmitter.emit("done");
});

Use a centralized broker or persist job state in Redis, SQS, RabbitMQ, or your database-backed workflow engine.

4. The model call is failing before the callback point

Sometimes people blame callbacks when the real issue is upstream. If AutoGen throws OpenAIError, 401 Unauthorized, 429 Too Many Requests, or Request timed out, your callback won’t execute because execution never reaches that branch.

try {
  await assistant.run("Process claim");
} catch (err) {
  console.error("AutoGen run failed:", err);
}

If you’re swallowing exceptions inside a wrapper, remove that wrapper first and let failures surface.

How to Debug It

  1. Confirm where the callback is registered

    • Log registration at startup and per request.
    • If you see registration happening inside every HTTP request handler, that’s a red flag.
  2. Log every boundary crossing

    • Add logs before run(), inside event handlers, and after completion.
    • You want to know whether execution stops before emission or after emission.
  3. Check whether you’re running multiple processes

    • If you use PM2, Kubernetes replicas, serverless functions, or worker threads, assume memory is not shared.
    • A callback registered in pod A will not fire for work executed in pod B.
  4. Turn on verbose error reporting

    • Catch and print full stack traces.
    • Look for messages like:
      • UnhandledPromiseRejection
      • TypeError
      • OpenAIError
      • RateLimitError
      • custom AutoGen runtime errors around event dispatch

Prevention

  • Register callbacks once at app bootstrap, not inside per-request code.
  • Treat agents as stateless unless you have explicit durable storage for state and events.
  • Use external queues or workflow engines when scaling beyond one process.
  • Keep handlers small and idempotent so retries don’t duplicate side effects.

If your “callback not firing when scaling” issue only appears after deployment, stop debugging AutoGen first and inspect your architecture. In most cases the bug is not in AutoGen TypeScript itself; it’s in how stateful listeners were carried into a distributed runtime where they can’t survive.


Keep learning

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

Related Guides