anomalyco / anomalyco/opencode

Bug: frontmatter sanitizer skips hyphenated keys, so allowed-tools breaks command/agent files

Open
#39,603 0 comments 0 reactions 1 assignee View on GitHub

@rekram1-node is already working on this.

Since Jul 30, 2026.

Dominant language
TypeScript
Stars
209k
Forks
27.5k
PR merge metrics
PR metrics pending

Description

Description

sanitize() in packages/core/src/config/markdown.ts exists so that "other coding agents accept unquoted colons in frontmatter values" keep working (comment on line 20). But its key pattern is:

const entry = line.match(/^([a-zA-Z_][a-zA-Z0-9_]*)\s*:\s*(.*)$/)

The character class has no -, so any hyphenated key fails to match, hits if (!entry) return [line], and is returned unsanitized. The retry matter(sanitize(content)) then throws exactly as the first attempt did.

This is unfortunate because allowed-tools is the single most common such key in other agents' command files - precisely the compatibility case the function was written for (see #6985 for .claude/commands/ compatibility).

Steps to reproduce

.opencode/command/review.md:

---
allowed-tools: Read: every file
description: Review helper
---
Review my code.

Actual - ConfigMarkdown.parse() throws Failed to parse YAML frontmatter: incomplete explicit mapping pair. Via parseOption() the error is swallowed and the whole frontmatter block leaks into the body:

data:    {}
content: "---
allowed-tools: Read: every file
description: Review helper
---
Review my code."

Expected:

data:    { "allowed-tools": "Read: every file", "description": "Review helper" }
content: "Review my code."

An underscore key is the control case and works fine - allowed_tools: Read: every file sanitizes correctly. Dotted keys (tools.read:) fail the same way as hyphenated ones.

Impact

Since parseOption() swallows the error and decode still returns a structurally valid object, the failure is silent:

  • Commands (config/plugin/command.ts:71) run with the raw YAML header, --- delimiters and all, pasted into the prompt sent to the model.
  • Agents (config/plugin/agent.ts:154) lose description, mode, model, steps and permissions entirely, and system becomes the raw file.
  • Skills (skill.ts:84) go through the same path.

OS

Windows (platform-independent - pure regex logic)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.