mastra-ai/mastra · error
Duplicate mode id " " found when creating the…
Error message
Duplicate mode id "${mode.id}" found when creating the AgentController What it means
validateModes runs when constructing an AgentController and enforces that every agent mode has a unique id. If two modes share the same id, it throws immediately at construction time so duplicate mode registrations fail fast rather than causing ambiguous mode resolution at runtime.
Solutions
- Give each mode in the modes array a unique id before constructing the controller
- Deduplicate merged mode lists (e.g. by id) prior to construction
- Check for double registration of the same mode from config files or plugins
Example fix
// before
modes: [{ id: 'chat', ... }, { id: 'chat', ... }]
// after
modes: [{ id: 'chat', ... }, { id: 'review', ... }] Defensive patterns
Strategy: validation
Validate before calling
function assertUniqueModeIds(modes: { id: string }[]): void {
const ids = modes.map(m => m.id);
if (new Set(ids).size !== ids.length) throw new Error('Duplicate mode ids: ' + ids.join(','));
}
assertUniqueModeIds(config.modes); Try / catch
try {
const controller = new AgentController(config);
} catch (e) {
if ((e as Error).message.startsWith('Duplicate mode id')) {
// dedupe config.modes by id and reconstruct
}
} Prevention
- Deduplicate mode arrays by id before constructing
- Never append the same mode object twice when merging configs
- Use constants for mode ids to avoid copy-paste drift
When it happens
Trigger: Passing a modes array to new AgentController(config) containing two AgentControllerMode objects with identical id values, e.g. copy-pasted mode definitions or merging mode lists from two sources without deduplication.
Common situations: Copy-pasting a mode config and forgetting to change its id; programmatically merging default and user modes that both define an 'edit' or 'ask' id; feature flags that append the same mode twice.
Related errors
- Default mode not found
- agent controller " " not found
- DATABASE_URL is required outside local development and…
- FACTORY_CREDENTIAL_ENCRYPTION_PREVIOUS_KEYS values must be…
- Google client ID is required. Provide it in the options or…
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/26feb9f3aa201fc5.
Report an issue: GitHub.
Appendix: source
Thrown at packages/core/src/agent-controller/agent-controller.ts:66
ToolCategory,
} from './types';
/**
* Registry key for the session map. JSON-encodes the (resourceId, scope) pair
* so the key is collision-proof for arbitrary strings: a scoped session can
* never collide with an unscoped one or with a different resource/scope split
* (e.g. `("a\0b", "c")` vs `("a", "b\0c")`).
*/
function sessionRegistryKey(resourceId: string, scope?: string): string {
return JSON.stringify([resourceId, scope ?? null]);
}
function validateModes(modes: AgentControllerMode[]): void {
const modeIds = new Set<string>();
for (const mode of modes) {
if (modeIds.has(mode.id)) {
throw new Error(`Duplicate mode id "${mode.id}" found when creating the AgentController`);
}
modeIds.add(mode.id);
const modeRecord = mode as unknown as { id: string; tools?: unknown; additionalTools?: unknown };
if (modeRecord.tools && modeRecord.additionalTools) {
throw new Error(
`Mode "${modeRecord.id}" cannot set both "tools" and "additionalTools" - choose replace OR augment`,
);
}
}
for (const mode of modes) {
if (mode.transitionsTo === mode.id) {
throw new Error(`Mode "${mode.id}" transitionsTo cannot reference itself`);
}
if (mode.transitionsTo && !modeIds.has(mode.transitionsTo)) {
throw new Error(`Mode "${mode.id}" transitionsTo references unknown mode "${mode.transitionsTo}"`);View on GitHub (pinned to 75dd419e61)