Repository navigation
[Bug] mavis skill show returns empty description for skills whose YAML frontmatter was added after daemon boot #110
Description
Summary
mavis skill show <name> returns "description": "" even when the on-disk SKILL.md has a clean YAML frontmatter block, the corresponding row exists in ~/.minimax/sqlite.db with the right description, and the agent tool can load the skill once prompted. The desktop daemon's in-memory skillIndex is populated only once at boot and is never refreshed when an already-indexed skill's file is rewritten.
Steps to reproduce
-
Open
MiniMax Code.appso the desktop daemon (PID 53290 in our environment) is up. -
Pick any skill whose
SKILL.mdoriginally lacked a YAML frontmatter block. The shipped bundle ships at least one (e.g.secure-by-design-review) and the legacy# Skill:header shape is easy to introduce by importing a marketplace bundle written before the YAML contract landed. -
Rewrite the file to add a canonical frontmatter block, save the file.
-
Re-run the same query without restarting the app:
$ mavis skill show secure-by-design-review | jq .description "" $ mavis skill ls mavis | jq '.skills[] | select(.name == "secure-by-design-review").description' null $ sqlite3 ~/.minimax/sqlite.db \ "SELECT length(description) FROM skills WHERE name='secure-by-design-review';" 142 $ # But the agent tool *can* load it: $ # claude /skill secure-by-design-review -> works
Expected
mavis skill show should return the on-disk description (or the row description, whichever wins) without a daemon restart.
Actual
show keeps returning "" until the daemon is restarted (launchctl kickstart -k gui/$UID/com.mavis.daemon on macOS). A clean restart sometimes still fails with Cannot find module 'better-sqlite3' in ~/.minavis/logs/launchd-stderr.log until MAVIS_SQLITE3_MODULE_PATH is exported to the app.asar.unpacked directory.
Root cause (reverse-engineered from MiniMax Code.app/Contents/Resources/resources/daemon/daemon.js)
In packages/skill/dist/skill.js (extracted from the bundled daemon.js):
async readSkill(req) {
const { skill_name, agent_name } = req;
// ... (fs lookup chain)
const meta = this.skillIndex.get(skill_name, actualAgentName); // in-memory cache
const fallback = meta ? null : this.frontmatterFallback(content);
const description2 = meta?.description ?? fallback?.description ?? "";
// ...
}skillIndex is hydrated at daemon boot from ~/.minimax/sqlite.db. Two failure modes compound:
- Boot-scan skip. If the file lacks valid YAML frontmatter at boot time, the indexer silently drops the row (the description is empty string). Without a row in
skills, every later API hit falls through tofrontmatterFallback(content), which also yields"". - Cache staleness. Even when a row is later
INSERT-ed by hand intoskills, the running daemon never refreshes its in-memoryskillIndex. The skill is invisible to the agent tool until restart.
Workaround (validated end-to-end on 2026-07-04)
A community skill patch is already in flight — see MiniMax-AI/skills#107 which adds skill-hygiene plus a reference doc with three recovery paths. The cleanest one is:
mavis skill update <name> -a mavis --file <absolute-path-to-SKILL.md>This invokes the file-watcher's onSkillFileChange handler in the daemon, which calls this.skillIndex.upsert(...) and brings the in-memory cache back in sync without restarting the desktop app.
A launchctl kickstart -k gui/$UID/com.mavis.daemon also works but forces the user to relaunch the whole UI; see workaround doc for MAVIS_SQLITE3_MODULE_PATH export if you go that route.
Proposed fix in the daemon
Two minimum-touch changes:
- Boot-scan must retry on
frontmatterFallback. Ifparsed?.descriptionis empty and the file has a# Skill:style header, attempt a tolerant fallback parse (regex over the first five lines, same algorithm as the community script) before giving up on the file. - File-watch must upsert on every change. The current
onSkillFileChangealready callsthis.skillIndex.upsert(...)when content changes — but the upsert guard rejects rows whosedescriptionis empty. Drop that guard, or better, fall back to the tolerant parse above wheneverparsed?.descriptionis empty.
A third, larger change is a mavis skill reindex [--agent <name>] [--skill <ref>] CLI command so contributors can recover from cache drift without a restart at all.
Environment
- Product:
MiniMax Code.app(bundle idcom.minimax.agent) - Daemon PID 53290 launched by the Electron app with
--port 15321 --owner electron --skip-pid-port - macOS 15.x, Apple Silicon
- ~/.minimax/sqlite.db size ~39 MB, schema includes
skills(PK name+agent_name),skill_hub,skill_hub_added - Reproduced on
secure-by-design-reviewand 48 other SKILL.md files in the bundled~/.minimax/skills/
Severity
Medium — the agent tool still loads the skill through available_skills once the user mentions it, but any tooling built on top of mavis skill show (publishing, marketplace linting, contribution checks) is silently broken until restart.
Activity
iamagenius00 commentedon Jul 5, 2026
Thanks for the detailed write-up and for sharing the workaround. We’ve tracked this down to the daemon’s skill index not refreshing properly. We’re working on a MiniMax Code update that should address this, and we’ll follow up here once the fix is available.
hetaoBackend commentedon Oct 19, 2026
Closing as part of a backlog cleanup: this issue was filed more than a month ago against an older release, and the codebase has changed substantially since then. If it still reproduces on the latest version, please open a new issue with the current version and reproduction steps. Thank you for the report!
批量清理积压:该 issue 创建已超过一个月,针对的是较旧版本,代码已有较大变化。如果在最新版本上仍能复现,欢迎附上当前版本号和复现步骤重新提交 issue。感谢反馈!