dotnet / dotnet/arcade-services

Support additional fenced JSON blocks in KBE issue bodies

Open
#6,578 0 comments 0 reactions 1 assignee Claimed by @michalpavelka View on GitHub
Dominant language
C#
Stars
86
Forks
86
Avg merge
1d 8h
Merged PRs (30d)
35

Description

## Problem

Build Analysis currently expects a KBE issue body to contain effectively one fenced JSON object. `KnownIssueHelper.GetKnownIssueJson` uses a greedy expression:

```csharp
```(json)?\s*({.*})\s*```
```

When an issue contains more than one matching fenced JSON object, the expression can capture from the first `{` through the last `}`. That combined content is not valid JSON, so Build Analysis cannot deserialize the KBE match instructions.

This prevents KBEs from using GitHub Agentic Workflows' [`safe-outputs.data`](https://github.github.com/gh-aw/reference/safe-outputs/) feature. For safe outputs with a `body`, the workflow appends the emitted `data` object as fenced JSON to the GitHub issue body, which introduces an additional JSON block.

## `safe-outputs.data` requirements

Per the [Safe Outputs reference](https://github.github.com/gh-aw/reference/safe-outputs/):

- `safe-outputs.data` must be explicitly enabled. Its default is `false`; use `data: true` to accept an arbitrary object, or provide a schema to validate the object.
- The data object is appended to a safe output body as fenced JSON.
- `create-issue.body` must be between 20 and 65,000 characters, including the appended data.

For example:

```yaml
safe-outputs:
create-issue:
labels: [Known Build Error]
data: true
```

A KBE created by such a workflow needs to retain its existing match-instruction JSON while also accepting the workflow-generated JSON data block.

## Proposed behavior

Replace the whole-body greedy JSON extraction with per-fence parsing:

1. Enumerate fenced JSON objects independently, preserving support for both ` ```json ` and untagged ` ``` ` fences.
2. Deserialize each candidate independently.
3. Treat a candidate as KBE match instructions only when it contains `ErrorMessage` or `ErrorPattern`.
4. Ignore unrelated or malformed JSON fences rather than allowing them to invalidate a valid KBE block.
5. When multiple KBE candidates are present, select the last valid one. This matches the existing method documentation and lets a later, intentionally updated KBE block take precedence.

This keeps existing KBEs compatible: a body with one valid KBE JSON block produces the same result as today, while a body containing unrelated fenced JSON—such as `safe-outputs.data`—continues to parse the KBE instructions correctly.

## Acceptance criteria

- A legacy KBE with one fenced JSON match-instruction block continues to parse unchanged.
- A KBE block followed by an unrelated `safe-outputs.data` fenced JSON block still uses the KBE's `ErrorMessage` or `ErrorPattern`.
- An unrelated JSON block before the KBE block does not affect parsing.
- Malformed or unrelated JSON blocks do not prevent a valid KBE block from being found.
- Multiple valid KBE instruction blocks resolve deterministically to the last valid block.
- Tests cover tagged and untagged JSON fences.

---

*This issue was authored with help from AI.*

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.