agentscope-ai/agentscope · error · ValueError
Invalid skill at {skill_path!r}: missing or malformed SKILL.
Error message
Invalid skill at {skill_path!r}: missing or malformed SKILL.md (requires 'name' and 'description' fields). What it means
Raised by LocalWorkspace.add_skill when the skill directory's SKILL.md is missing or does not contain both 'name' and 'description' fields (parsed during _validate_and_hash_skill). The library requires every skill to be a directory with a well-formed SKILL.md before it can be copied into the agent's skills partition. This is a validation error on user-supplied skill content.
Source
Thrown at src/agentscope/workspace/_local_workspace.py:797
Args:
skill_path (`str`):
Absolute or relative path to the skill directory to copy.
agent_id (`str | None`, optional):
The agent taking ownership. ``None`` installs into the
default partition.
Raises:
ValueError: If the skill at ``skill_path`` is invalid (missing or
malformed ``SKILL.md``).
"""
skill_path = _normalize_local_path(skill_path)
skills_dir = await self._equip_partition(agent_id)
async with self._skill_lock:
os.makedirs(skills_dir, exist_ok=True)
result = await self._validate_and_hash_skill(skill_path)
if result is None:
raise ValueError(
f"Invalid skill at {skill_path!r}: missing or malformed "
"SKILL.md (requires 'name' and 'description' fields).",
)
_, raw_name, skill_hash = result
skills_file = await self._load_skills_file(skills_dir)
existing: dict[str, _SkillEntry] = skills_file["skills"]
existing_hashes: set[str] = {e["hash"] for e in existing.values()}
if skill_hash in existing_hashes:
logger.info(
"Skill '%s' (hash: %s...) already exists, skipping",
raw_name,
skill_hash[:8],
)
return
View on GitHub (pinned to e90f1c7592)
Solutions
- Inspect skill_path: confirm SKILL.md exists at its root and starts with valid front-matter containing non-empty 'name' and 'description'.
- If using add_skill_archive, re-pack the archive so its root (or a single top-level dir) contains SKILL.md directly.
- Validate SKILL.md parses as expected (e.g. python -c "import frontmatter; print(frontmatter.load('SKILL.md'))") before passing it.
- Fix any YAML syntax errors (tabs, missing colons, unquoted special characters) in SKILL.md.
Example fix
# before
await ws.add_skill("./my-skill") # my-skill/SKILL.md missing 'description'
# after
# my-skill/SKILL.md
---
name: my-skill
description: Formats reports
---
await ws.add_skill("./my-skill") Defensive patterns
Strategy: validation
Validate before calling
import pathlib, frontmatter
def skill_is_valid(skill_path: str) -> bool:
md = pathlib.Path(skill_path) / "SKILL.md"
if not md.is_file():
return False
try:
post = frontmatter.load(md)
except Exception:
return False
return bool(post.get("name")) and bool(post.get("description")) Try / catch
try:
await ws.add_skill(path)
except ValueError as e:
if "SKILL.md" in str(e):
log.warning("skill %s skipped: %s", path, e)
else:
raise Prevention
- Ship a skill template with valid SKILL.md front-matter.
- Validate SKILL.md in CI with a frontmatter parser before packaging.
- Pack archives from inside the skill directory so SKILL.md is at the root.
When it happens
Trigger: Calling add_skill(path) or add_skill_archive(...) where path (or the archive's skill root) has no SKILL.md, or the SKILL.md front-matter/table lacks a 'name' or 'description' entry; also triggered by an archive whose extracted root is not the skill directory itself.
Common situations: Zipping a skill folder's parent instead of the folder, typos in SKILL.md keys (e.g. 'desc' instead of 'description'), empty SKILL.md, YAML front-matter indentation errors, or pointing add_skill at a README-only directory.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- No SKILL.md at the root of {root!r}.
- Skill path {skill_path!r} resolves outside skills_dir.
- Input validation failed for tool '{tool_call.name}': {e.mess
- The injection template must contain the '{runtime_state}' pl
- Expected a 5-field cron expression, got {record.data.cron_ex
AI-assisted analysis of agentscope-ai/agentscope@e90f1c7592 (2026-08-28).
Data as JSON: /api/errors/54733a773bbbbd88.
Report an issue: GitHub.