Skip to content

Python: .NET: [Bug]: SKILL.md frontmatter drops the continuation lines of a multi-line description #9392

Open

Description

Observed Behavior

AgentFileSkillsSource reads the SKILL.md frontmatter with regular expressions. A value ends at the end of its line. When a description continues on indented lines (a multi-line plain scalar, valid YAML), only the first line is kept and the rest is dropped without a warning. The skill list that the provider writes into the instructions then gives the model an incomplete description, for example:

<description>Summarize a meeting transcript into decisions and action</description>

The part that tells the model when to use the skill ("Use when ...") is usually in the lost lines, so the model loads skills less reliably.

Expected Behavior

The description holds the full value, as a YAML parser reads it: "Summarize a meeting transcript into decisions and action items. Use when the user shares a transcript or asks for meeting notes." The Agent Skills specification (https://agentskills.io/specification) requires YAML frontmatter. If the parser supports only one-line values, a warning for a continued value would make the problem visible.

Steps to Reproduce

  1. Create skills/meeting-notes/SKILL.md with the frontmatter below.
  2. Create an AgentSkillsProvider for the folder skills and add it to an agent.
  3. Run the agent and look at the instructions sent to the model (or at the AgentSkillFrontmatter.Description of the loaded skill).
  4. The description holds only its first line.

Minimal Reproduction

---
name: meeting-notes
description: Summarize a meeting transcript into decisions and action
  items. Use when the user shares a transcript or asks for meeting notes.
---
Body.
var skills = new AgentSkillsProvider("skills", options: new AgentSkillsProviderOptions { DisableLoadSkillApproval = true }, loggerFactory: null);
// Add `skills` to ChatClientAgentOptions.AIContextProviders and run one turn.
// The skill list in the system message shows: "Summarize a meeting transcript into decisions and action"

The key-value pattern of 1.20.0, ^([\w-]+)\s*:\s*(?:["'](.+?)["']|(.+?))\s*$, and the refined pattern on main after #8430 (s_yamlKeyValueRegex in dotnet/src/Microsoft.Agents.AI/Skills/File/AgentFileSkillsSource.cs) both stop at the end of the first line for this input.

Error Messages and Stack Traces

None. No warning is logged.

Package Versions

Microsoft.Agents.AI: 1.20.0 (the pattern on main behaves the same)

.NET Version

.NET 10.0

Operating System

Linux

Regression

No

Additional Context

A folded block scalar, a common way to write a long description, also fails: with the pattern on main, description: > followed by indented lines gives the value ">". The Python implementation was not checked.

Acknowledgements

  • I searched existing issues and did not find a duplicate.
  • I personally verified this behavior and the reproduction details are authentic.
  • I will wait for explicit maintainer agreement before starting implementation of a non-trivial change.

Activity

  1. added
    .NETUsage: [Issues, PRs], Target: .Net
    pythonUsage: [Issues, PRs], Target: Python
    triageUsage: [Issues], Target: All issues that still need to be triaged
    on Oct 14, 2026
  2. changed the title [-].NET: [Bug]: SKILL.md frontmatter drops the continuation lines of a multi-line description[/-] [+]Python: .NET: [Bug]: SKILL.md frontmatter drops the continuation lines of a multi-line description[/+] on Oct 14, 2026
  3. added
    reproducedUsage: [Issues], Target: all issues that can be reproduced by the triage workflow
    on Oct 14, 2026
  4. github-actions commented on Oct 14, 2026

    @github-actions
    Contributor

    🤖 Automated triage reproduction notes (agent-authored — trust but verify)

    Agent analysis

    Repro: dotnet/src/Microsoft.Agents.AI/Skills/File/AgentFileSkillsSource.cs::TryParseFrontmatter truncates a plain YAML description when its value starts inline and continues on indented lines; ParseYamlScalarValue returns the first-line capture for non-block scalars. Minimal repro: write the issue's SKILL.md, load it with AgentFileSkillsSource.GetSkillsAsync, and assert Frontmatter.Description equals the YAML-folded full value.

    • Failing test: dotnet/tests/Microsoft.Agents.AI.UnitTests/AgentSkills/FileAgentSkillLoaderTests.cs
    • Files examined: dotnet/src/Microsoft.Agents.AI/Skills/File/AgentFileSkillsSource.cs, dotnet/src/Microsoft.Agents.AI/Skills/AgentSkillsProvider.cs, dotnet/tests/Microsoft.Agents.AI.UnitTests/AgentSkills/FileAgentSkillLoaderTests.cs, dotnet/nuget/nuget-package.props
    • Tests run: GetSkillsAsync_MultilinePlainDescription_FoldsContinuationLinesAsync, GetSkillsAsync_ExistingScalarFormats_PreservedAsync
    • Reported version: 1.20.0
    • Current version: 1.24.0
  5. added
    agentsUsage: [Issues, PRs], Target: Single agent
    and removed
    triageUsage: [Issues], Target: All issues that still need to be triaged
    on Oct 14, 2026
  6. Ayoubhm07 commented on Oct 21, 2026

    @Ayoubhm07
    Contributor

    I checked the Python side, since the issue carries both labels and the triage note only covers AgentFileSkillsSource.cs. On main at 30bc5c1, FileSkillsSource returns the full description for the issue's SKILL.md with LF and with CRLF line endings, and for a > folded block, because _extract_frontmatter parses the block with yaml.compose. As far as I can tell only the .NET regex is affected.

  7. jaliyaudagedara commented on Oct 22, 2026

    @jaliyaudagedara

    I'd like to take this one. I have a fix ready (diff) and wanted to check the direction before opening a PR.

    This is .NET only. Python already handles it (PyYAML since #8430, as mentioned above).

    The fix

    In AgentFileSkillsSource.ParseYamlScalarValue, plain values now pick up their indented continuation lines, the same way YAML does:

    description: Summarize a meeting transcript into decisions and action
      items. Use when the user shares a transcript.
    • Before: Summarize a meeting transcript into decisions and action
    • After: Summarize a meeting transcript into decisions and action items. Use when the user shares a transcript.

    Quoted values and | / > blocks work as before. No new dependency and no public API change.

    Lists stay as they are

    A list or nested mapping isn't joined into one string:

    allowed-tools:
      - Read
      - Write

    This still gives - Read, same as today.

    One extra check

    TryParseFrontmatter now calls ValidateCompatibility. Today a compatibility value over 500 characters makes the AgentSkillFrontmatter constructor throw. Nothing catches it, so one bad SKILL.md stops every skill from loading. The fix makes long values easier to hit, so I added the check.

    Worth knowing

    • This applies to every top-level field, not just description. A continued allowed-tools now includes all the listed tools.
    • A name split over two lines now fails validation instead of loading truncated.
    • Metadata values and multi-line quoted values are unchanged. Happy to do those as a follow-up.

    Tests are in FileAgentSkillLoaderTests. The AgentSkills tests pass on net10.0 and net472.

    Question

    In #8430, Eduard van Valkenburg (@eavanvalkenburg) suggested a YAML package, and SergeyMenshykh said .NET could follow up once one is agreed. Would you take this smaller fix in the meantime, or wait for that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

.NETUsage: [Issues, PRs], Target: .NetagentsUsage: [Issues, PRs], Target: Single agentpythonUsage: [Issues, PRs], Target: PythonreproducedUsage: [Issues], Target: all issues that can be reproduced by the triage workflow

Type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions