How to Fix 'callback not firing during development' in CrewAI (TypeScript)
If you’re seeing callback not firing during development in CrewAI TypeScript, it usually means your task completed but the callback never executed in the path you expected. In practice, this shows up during local runs when the agent finishes, but your handler never logs, persists, or returns anything.
Most of the time, this is not a CrewAI bug. It’s a lifecycle issue: the callback is either attached to the wrong object, not awaited, or gets lost because the process exits before async work completes.
The Most Common Cause
The #1 cause is wiring the callback incorrectly on a Task or Agent, then expecting it to behave like a normal event listener. In CrewAI TypeScript, callbacks need to be attached where the framework actually invokes them, and async callbacks must be awaited all the way through.
Here’s the broken pattern:
| Broken | Fixed |
|---|---|
| Callback attached too late / not awaited | Callback passed into the right execution path and awaited |
// broken.ts
import { Agent, Task, Crew } from "crewai";
const agent = new Agent({
role: "Researcher",
goal: "Summarize customer complaints",
});
const task = new Task({
description: "Summarize support tickets",
agent,
});
task.callback = async (result) => {
console.log("Callback fired:", result);
await saveToDb(result);
};
const crew = new Crew({
agents: [agent],
tasks: [task],
});
crew.kickoff(); // not awaited
// fixed.ts
import { Agent, Task, Crew } from "crewai";
const agent = new Agent({
role: "Researcher",
goal: "Summarize customer complaints",
});
const task = new Task({
description: "Summarize support tickets",
agent,
callback: async (result) => {
console.log("Callback fired:", result);
await saveToDb(result);
},
});
const crew = new Crew({
agents: [agent],
tasks: [task],
});
await crew.kickoff(); // wait for task lifecycle to complete
The important part is that crew.kickoff() must stay alive long enough for the callback chain to complete. If you start execution and immediately let Node exit, your callback can look “missing” even though it was scheduled.
If your callback does I/O like DB writes, file writes, or HTTP calls, make sure those promises are awaited inside the callback too.
Other Possible Causes
1. You’re using an inline callback with a stale closure
If your callback captures variables that are mutated later, it may look like it didn’t fire because it wrote bad data or hit an exception.
let runId = "";
const task = new Task({
description: "Process invoice",
agent,
callback: async (result) => {
console.log("runId:", runId); // empty if set later
await audit(runId, result);
},
});
runId = crypto.randomUUID();
Fix by setting state before creating the task:
const runId = crypto.randomUUID();
const task = new Task({
description: "Process invoice",
agent,
callback: async (result) => {
await audit(runId, result);
},
});
2. The callback throws before logging anything useful
A thrown error inside callback can make it seem like it never ran. In dev mode, you may only see a generic failure around Crew.kickoff().
callback: async (result) => {
const parsed = JSON.parse(result.output); // throws if output is not JSON
await persist(parsed);
}
Wrap it explicitly:
callback: async (result) => {
try {
const parsed = JSON.parse(result.output);
await persist(parsed);
console.log("callback completed");
} catch (err) {
console.error("callback failed", err);
throw err;
}
}
3. You attached the callback to Agent when your version expects it on Task
CrewAI TypeScript APIs have changed across versions. If you’re following Python examples or older TS docs, you may be putting hooks on the wrong class.
// wrong for many TS setups
const agent = new Agent({
role: "Analyst",
goal: "Review claims",
callback: async () => {
console.log("never called");
},
});
Prefer attaching at task execution time:
const task = new Task({
description: "Review claims",
agent,
callback: async (result) => {
console.log("task callback called", result);
},
});
4. Your dev server hot reload is killing the process mid-run
With tsx, nodemon, or Next.js API routes, file changes can restart Node before your callback finishes.
{
"scripts": {
"dev": "nodemon src/index.ts"
}
}
If a long-running task is involved, run it outside hot reload first:
{
"scripts": {
"dev": "tsx watch src/index.ts",
"start": "node dist/index.js"
}
}
And test with a plain one-shot process:
node dist/index.js
How to Debug It
- •
Confirm whether
kickoff()is awaited- •Search for
crew.kickoff()and make sure every call site usesawait. - •If you’re in an Express route or serverless function, return only after the promise resolves.
- •Search for
- •
Add logs at three points
- •Before kickoff.
- •Inside the callback.
- •After kickoff.
console.log("before kickoff"); const result = await crew.kickoff(); console.log("after kickoff", result); // inside callback: console.log("inside callback"); - •
Force a failure inside the callback
- •Temporarily throw an error:
callback: async () => { throw new Error("test callback path"); }If you don’t see that error surface from
Crew.kickoff(), your hook isn’t wired into execution. - •
Check package version and API shape
- •Verify whether your installed version supports callbacks on
Task,Agent, or only at crew level. - •Inspect types directly:
npm ls crewaiThen check IntelliSense on
new Task({ ... })instead of trusting blog snippets. - •Verify whether your installed version supports callbacks on
Prevention
- •Always await both
crew.kickoff()and any async work inside callbacks. - •Keep callbacks small; move persistence and network calls into dedicated services.
- •Pin your CrewAI version and verify API examples against that exact release.
- •In dev environments with hot reload, test long-running flows in a plain Node process first.
If you still see callback not firing during development, treat it as a wiring problem first, not an orchestration problem. In CrewAI TypeScript, most “missing” callbacks are really promises that were never awaited or hooks attached to the wrong object.
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