mastra-ai/mastra · error
Duplicate workspace tool name "${exposedName}": tool "${name
Error message
Duplicate workspace tool name "${exposedName}": tool "${name}" conflicts with an already-registered tool. Check your tools config for duplicate "name" values. What it means
Workspace tool registration keys tools by their exposed name (`config.name ?? defaultName`). If two tool configs resolve to the same exposed name, `addTool` throws a duplicate-name Error so registration fails fast rather than silently overwriting a tool. The error names both the internal tool and the colliding exposed name.
Source
Thrown at packages/core/src/workspace/tools/tools.ts:466
workspace: ctx?.workspace ?? workspace,
},
true,
),
};
} else {
wrapped = { ...tool, requireApproval: config.requireApproval };
}
if (opts?.readTrackerMode) {
wrapped = wrapWithReadTracker(wrapped, workspace, readTracker, config, opts.readTrackerMode);
} else {
wrapped = wrapTool(wrapped, workspace, opts?.targets ?? {});
}
// Use custom name if provided, otherwise use the default constant name
const exposedName = config.name ?? name;
if (tools[exposedName]) {
throw new Error(
`Duplicate workspace tool name "${exposedName}": tool "${name}" conflicts with an already-registered tool. ` +
`Check your tools config for duplicate "name" values.`,
);
}
// When the tool is renamed, update its id to match so fallback-by-id
// resolution (in tool-call-step, llm-execution-step, etc.) won't allow
// the model to call the tool using the old default name.
if (exposedName !== name && 'id' in wrapped) {
wrapped = { ...wrapped, id: exposedName };
}
if (config.hooks) {
wrapped = wrapWithToolHooks(wrapped, config.hooks, exposedName, name);
}
// Write lock is outermost — serializes the entire enriched execute pipeline
if (opts?.useWriteLock) {
wrapped = wrapWithWriteLock(wrapped, writeLock);View on GitHub (pinned to 75dd419e61)
Solutions
- Give each conflicting tool config a unique `name`
- Remove the duplicate config entry if it was added by mistake
- If two instances of the same built-in tool are needed with different settings, expose them under distinct names
Example fix
// before
{ tool: 'read-file', name: 'read' },
{ tool: 'read-many-files', name: 'read' } // duplicate
// after
{ tool: 'read-file', name: 'read' },
{ tool: 'read-many-files', name: 'read-many' } Defensive patterns
Strategy: validation
Validate before calling
const names = toolConfigs.map(c => c.name ?? defaultNameFor(c.tool));
const dupes = names.filter((n, i) => names.indexOf(n) !== i);
if (dupes.length) throw new Error(`Duplicate workspace tool names: ${[...new Set(dupes)].join(', ')}`); Try / catch
try {
const tools = createWorkspaceToolConfigs(configs);
} catch (err) {
if (err instanceof Error && err.message.startsWith('Duplicate workspace tool name')) {
console.error(err.message); // fix config names
throw err;
}
throw err;
} Prevention
- Uniquely name every custom tool config; keep names in one constants file to spot collisions
- Avoid enabling the same built-in tool twice without renaming one
- Add a config-lint test that builds the tools map and asserts no duplicate keys
When it happens
Trigger: Providing the same custom `name` for two different tool configs, or enabling the same built-in workspace tool twice (e.g. two read-file entries) so both map to one constant default name.
Common situations: Copy-pasting a tool config entry and forgetting to change `name`; spreading arrays of tool configs that both contain a renamed tool with the same name; dynamic config generation producing duplicate names.
Related errors
- Skill not found: ${invocation.skillName}.
- Project path is required
- A session workspace must be a valid Workspace instance.
- MASTRA_ADD_WORKSPACE_MISSING_AGENT_METADATA
- CompositeFilesystem requires at least one mount
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/8dfa00bec74c51c7.
Report an issue: GitHub.