Skip to content

fix(skills): match SKILL.md frontmatter delimiters as whole lines - #7726

Closed
alphasafal wants to merge 1 commit into
google:mainfrom
alphasafal:fix/skill-frontmatter-delimiter-line
Closed

alphasafal wants to merge 1 commit into
google:mainfrom
alphasafal:fix/skill-frontmatter-delimiter-line

Conversation

@alphasafal

Copy link
Copy Markdown
Contributor

Please ensure you have read the contribution guide before creating a pull request.

Link to Issue or Description of Change

1. Link to an existing issue (if applicable):

Problem:
_parse_skill_md_content split SKILL.md with content.split("---", 2), so the frontmatter ended at the first --- anywhere, including inside a value. An unquoted description: Compare A --- B was cut to Compare A with the rest leaking into the instructions, a quoted one failed with Invalid YAML in frontmatter, and keys after a | block scalar containing a --- line were dropped.

Solution:
Match the opening and closing delimiters as whole --- lines with a module-level regex (_FRONTMATTER_PATTERN). The existing checks and error messages are unchanged: a file not starting with --- and a frontmatter with no closing --- line raise the same ValueErrors as before. CRLF line endings are handled. A closing --- with other text after it on the same line is no longer accepted as the delimiter, which matches how YAML frontmatter is normally delimited.

Testing Plan

Unit Tests:

  • I have added or updated unit tests for my change.
  • The skills unit tests pass locally (I ran tests/unittests/skills, not the full suite).

New tests in tests/unittests/skills/test__utils.py:

  • test__load_skill_from_dir_dashes_inside_frontmatter_value (unquoted, quoted and block-scalar values containing ---): all three fail on main and pass with this change.
  • test__load_skill_from_dir_crlf_frontmatter: guards Windows line endings.
pytest tests/unittests/skills
108 passed

isort 8.0.1 and pyink 25.12 report no changes on the edited files.

Manual End-to-End (E2E) Tests:

The reproduction from #7725 with google.adk.skills.load_skill_from_dir:

before: description='Compare two options', instructions='pros, cons and a verdict.\n---\n# Instructions\nDo the thing.'
after:  description='Compare two options --- pros, cons and a verdict.', instructions='# Instructions\nDo the thing.'

Checklist

  • I have read the CONTRIBUTING.md document.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing skills unit tests pass locally with my changes.
  • I have manually tested my changes end-to-end.
  • Any dependent changes have been merged and published in downstream modules.

Additional context

All skill loaders go through this function (load_skill_from_dir, zip loading, GCS loading), so the fix covers each of them.

@google-cla

google-cla Bot commented Oct 25, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

_parse_skill_md_content split the file on the first "---" anywhere, so a "---" inside a frontmatter value ended the frontmatter early. An unquoted description was cut short and the rest leaked into the instructions, a quoted one failed to load with "Invalid YAML in frontmatter", and keys after a block scalar were dropped. Match the opening and closing "---" as whole lines instead.
@alphasafal
alphasafal force-pushed the fix/skill-frontmatter-delimiter-line branch from 7c05c2b to 7792c76 Compare October 25, 2026 15:34

@BichengWang BichengWang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 7792c76. I reproduced all three new description cases failing with the base parser, then ran the skills tests excluding GCS: 92 passed, 16 deselected. I also checked directory and ZIP loading with CRLF, an EOF closing delimiter, trailing delimiter whitespace, and a horizontal rule in the body; all preserved the description and instructions. Malformed closing delimiters still raise the expected error.

No blocking findings. The line anchors correctly leave indented --- inside a block scalar alone. I couldn't run the GCS tests because the optional storage dependency isn't available in the offline cache; I didn't run the full suite.

@alphasafal

Copy link
Copy Markdown
Contributor Author

Thanks @BichengWang for the thorough review, especially the extra CRLF, EOF-delimiter and ZIP checks.

To close the gap you mentioned, I ran the full skills suite with google-cloud-storage installed: pytest tests/unittests/skills gives 108 passed, including the 16 GCS tests (-k gcs: 16 passed).

copybara-service Bot pushed a commit that referenced this pull request Oct 26, 2026
Merge #7726

A `---` inside a frontmatter value no longer ends the frontmatter. The
closing delimiter must now be a line of only `---` (trailing spaces
allowed): a SKILL.md whose closing `---` has other text on the same line,
which was previously accepted with that text moved into the instructions,
now raises ValueError.

Fixes #7725

PiperOrigin-RevId: 1007645341
@adk-bot

adk-bot commented Oct 26, 2026

Copy link
Copy Markdown
Collaborator

Thank you @alphasafal for your contribution! 🎉

Your changes have been successfully imported and merged via Copybara in commit 25105b4.

Closing this PR as the changes are now in the main branch.

@adk-bot adk-bot added the merged [Status] This PR is merged label Oct 26, 2026
@adk-bot adk-bot closed this Oct 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merged [Status] This PR is merged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SKILL.md frontmatter is cut at the first "---" inside a value (description truncated or skill fails to load)

4 participants