agentscope-ai/agentscope · error · ValueError
A skill named {skill_record.name!r} already exists for this
Error message
A skill named {skill_record.name!r} already exists for this user. What it means
Raised by SQLStorage.upsert_skill when a skill record's name is already owned by a different skill record for the same user. Skill names are unique per user; the guard compares the stored record's id to skill_record.id and rejects the write on mismatch.
Source
Thrown at src/agentscope/app/storage/_sql/_storage.py:914
MCPRow.id == mcp_id,
MCPRow.user_id == user_id,
),
)
await sess.commit()
return result.rowcount > 0
async def upsert_skill(
self,
user_id: str,
skill_record: SkillRecord,
) -> str:
"""Create or update an installed-skill record for *user_id*.
Same contract as :meth:`RedisStorage.upsert_skill`.
"""
holder = await self.get_skill_by_name(user_id, skill_record.name)
if holder is not None and holder.id != skill_record.id:
raise ValueError(
f"A skill named {skill_record.name!r} already exists for "
f"this user.",
)
skill_record.user_id = user_id
await self._write_row(SkillRow, skill_record)
return skill_record.id
async def list_skills(self, user_id: str) -> list[SkillRecord]:
"""Return every installed-skill record for *user_id*."""
from sqlalchemy import select
async with self._session() as sess:
rows = (
(
await sess.execute(
select(SkillRow).where(SkillRow.user_id == user_id),
)
)View on GitHub (pinned to e90f1c7592)
Solutions
- Rename the incoming skill to something unique for that user
- Fetch the existing skill via get_skill_by_name and update it in place, preserving its id
- Remove the old conflicting skill before installing the new one
Example fix
// before
await storage.upsert_skill(user_id, SkillRecord(id=fresh, name="search"))
// after
old = await storage.get_skill_by_name(user_id, "search")
if old:
await storage.delete_skill(user_id, old.id)
await storage.upsert_skill(user_id, SkillRecord(name="search", ...)) Defensive patterns
Strategy: validation
Validate before calling
if (dup := await storage.get_skill_by_name(user_id, rec.name)) and dup.id != rec.id:\n raise Exception(f\"skill name {rec.name!r} taken\") Try / catch
try:\n await storage.upsert_skill(user_id, rec)\nexcept ValueError as e:\n if \"already exists\" in str(e): rename_or_merge(rec)\n else: raise
Prevention
- Namespace skill names by source/package
- Check get_skill_by_name before install flows
When it happens
Trigger: Calling upsert_skill(user_id, record) where record.name collides with another skill of that user and record.id is not the existing record's id.
Common situations: Installing a second skill with the same display name; reinstalling a skill after its record was recreated with a fresh id; syncing skills between machines without carrying ids.
Related errors
- An MCP named {mcp_record.name!r} already exists for this use
- Bot {platform_bot_id!r} already drives channel {holder!r}.
- Session {session_id!r} not found.
AI-assisted analysis of agentscope-ai/agentscope@e90f1c7592 (2026-08-28).
Data as JSON: /api/errors/24ac12b28b72d0b7.
Report an issue: GitHub.