mastra-ai/mastra · error
[WorkspaceSkills] Cannot resolve skill "${winner.name}": mul
Error message
[WorkspaceSkills] Cannot resolve skill "${winner.name}": multiple ${winner.source.type} skills found at ${paths}. Rename one or move it to a different source type. What it means
WorkspaceSkills resolves skills by name across multiple sources (local, repo, published, etc.) using source-type priority as a tiebreaker. When the top two candidates share the same source type, priority cannot disambiguate, so #tieBreak throws instead of silently picking one. The message lists every same-type path so the developer can rename or relocate the duplicates.
Source
Thrown at packages/core/src/workspace/skills/workspace-skills.ts:359
const SOURCE_PRIORITY: Record<string, number> = { local: 0, managed: 1, external: 2 };
const sorted = [...deduped].sort((a, b) => {
const aPri = SOURCE_PRIORITY[a.source.type] ?? 99;
const bPri = SOURCE_PRIORITY[b.source.type] ?? 99;
if (aPri !== bPri) return aPri - bPri;
return a.path.localeCompare(b.path);
});
const winner = sorted[0]!;
const runnerUp = sorted[1]!;
// Error if source-type priority can't break the tie
if (winner.source.type === runnerUp.source.type) {
const paths = sorted
.filter(s => s.source.type === winner.source.type)
.map(s => `"${s.path}"`)
.join(', ');
throw new Error(
`[WorkspaceSkills] Cannot resolve skill "${winner.name}": multiple ${winner.source.type} skills found at ${paths}. ` +
`Rename one or move it to a different source type.`,
);
}
console.warn(
`[WorkspaceSkills] Multiple skills named "${winner.name}" found. ` +
`Using "${winner.path}" (source: ${winner.source.type}). ` +
`Other candidates: ${sorted
.slice(1)
.map(s => `"${s.path}" (${s.source.type})`)
.join(', ')}`,
);
return winner;
}
async refresh(): Promise<void> {View on GitHub (pinned to 75dd419e61)
Solutions
- Rename one of the conflicting skills (its directory and/or the name field in its SKILL.md frontmatter) so names are unique.
- Move one duplicate to a different source type (e.g. from local to repo scope) so priority can break the tie.
- Delete the stale duplicate if it's an leftover copy.
- List available skills first and reference the intended one unambiguously.
Example fix
// before // skills/brand-guidelines/SKILL.md -> name: brand-guidelines // backup/brand-guidelines/SKILL.md -> name: brand-guidelines (duplicate) // after // backup/brand-guidelines/SKILL.md -> name: brand-guidelines-legacy
Defensive patterns
Strategy: validation
Validate before calling
const matches = await workspaceSkills.list().then(all => all.filter(s => s.name === 'brand-guidelines'));
const sameType = new Set(matches.map(m => m.source.type));
if (matches.length > 1 && sameType.size === matches.length && matches.length > 1) {
throw new Error(`Duplicate skill name 'brand-guidelines' in the same source type — rename one before resolving by name.`);
} Try / catch
try {
const skill = await workspaceSkills.skill('brand-guidelines');
} catch (err) {
if (err instanceof Error && err.message.includes('Cannot resolve skill')) {
// prompt user to disambiguate or fall back to a default skill
} else throw err;
} Prevention
- Enforce unique skill names within each source type via lint/CI checks on SKILL.md frontmatter.
- Update the frontmatter name whenever you copy or fork a skill directory.
- Prefer explicit path-based access when duplicates may temporarily exist.
- Read the error's path list to find exactly which duplicates to rename.
When it happens
Trigger: Requesting a skill by name when two or more skills with that exact name exist in the same source type — e.g. two 'brand-guidelines' directories in the same local skills folder, or duplicate names across repos mapped to the same source type.
Common situations: Cloning/renaming a skill folder and forgetting to update its name in SKILL.md frontmatter; merging branches that each added a skill with the same name; syncing skills between projects without renaming; case-only differences deduplicated into the same name.
Related errors
- No workspace with skills configured
- AcpAgent does not support resuming suspended generate calls
- ACP prompt stopped before completing: ${response.stopReason}
- Auth0 domain and audience are required, please provide them
- Cookie password must be at least 32 characters for SSO. Set
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/1814809002b22a41.
Report an issue: GitHub.