mastra-ai/mastra · error
AgentControllerChannels is not bound to an AgentController.
Error message
AgentControllerChannels is not bound to an AgentController. Pass it via `channels` in AgentControllerConfig.
What it means
AgentControllerChannels requires a bound AgentController instance to operate. This plain Error is thrown when any channel method calls requireController() before the controller was injected. The binding happens only when the channels object is passed via `channels` in AgentControllerConfig.
Source
Thrown at packages/core/src/channels/agent-controller-channels.ts:493
if (!run) {
run = (async () => {
try {
await onSessionStart({ session, thread, requestContext });
} catch (error) {
// Best-effort by contract: a session that couldn't be configured
// still answers the message, on whatever defaults it was created
// with.
this.log('error', `Channel session-start hook failed for resourceId=${thread.resourceId}: ${error}`);
}
})();
this.sessionStartRuns.set(session, run);
}
await run;
}
private requireController(): AgentController<any> {
if (!this.controller) {
throw new Error(
'AgentControllerChannels is not bound to an AgentController. Pass it via `channels` in AgentControllerConfig.',
);
}
return this.controller;
}
}
View on GitHub (pinned to 75dd419e61)
Solutions
- Pass the AgentControllerChannels instance via `channels` in your AgentControllerConfig so it gets bound at construction.
- Ensure you call channel methods on/after the controller binding, not on an unbound standalone instance.
- In tests, construct the AgentController first and hand the channels object to its config instead of instantiating the channels class alone.
Example fix
// before
const channels = new AgentControllerChannels();
channels.controller; // throws
// after
const controller = new Agent({ ...config, channels: new AgentControllerChannels() }); Defensive patterns
Strategy: validation
Validate before calling
if (!channelsInstance || channelsInstance.controller === undefined) throw new Error('AgentControllerChannels must be passed via AgentControllerConfig.channels'); Type guard
function isBound(ch: AgentControllerChannels): boolean { return !!ch.controller; } Try / catch
try { requireBound(channels).someMethod(); } catch (e) { throw new Error('Wire channels into AgentControllerConfig first', { cause: e }); } Prevention
- Always construct channels via AgentControllerConfig, never standalone in app code
- In tests, assert the binding right after controller construction
- Call channel methods only through the controller, not on the raw channels object
When it happens
Trigger: Instantiating AgentControllerChannels directly and calling methods (e.g. via `controller` accessor) without registering it on an AgentController through AgentControllerConfig.channels.
Common situations: Constructing the channels helper standalone in tests or scripts; forgetting to wire `channels` into the AgentController config; passing the channels object after the controller was already created without re-binding.
Related errors
- MastraFactory: integrations [${channelRegistrations.map(({ i
- Channels require storage to be configured on the Mastra inst
- No adapter for platform "${platform}"
- chat module not loaded yet — call getChatModule() first
- Channel "${platform}" is not registered. Available: ${availa
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/b9ae61558952f188.
Report an issue: GitHub.