chat: handle invalid URIs in extractCodeblockUrisFromText#309308
Merged
roblourens merged 2 commits intomainfrom Apr 13, 2026
Merged
chat: handle invalid URIs in extractCodeblockUrisFromText#309308roblourens merged 2 commits intomainfrom
roblourens merged 2 commits intomainfrom
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes a crash in the chat renderer when <vscode_codeblock_uri>...</vscode_codeblock_uri> tags contain non-URI text (e.g. markdown code fences) by making URI extraction tolerant of parse failures.
Changes:
- Wrap
URI.parse()inextractCodeblockUrisFromTextwith a try/catch and returnundefinedon parse failure. - Add a unit test covering invalid (non-URI) content inside the codeblock URI tag.
Show a summary per file
| File | Description |
|---|---|
| src/vs/workbench/contrib/chat/common/widget/annotations.ts | Prevents renderer crashes by safely handling invalid URI strings when extracting codeblock URIs. |
| src/vs/workbench/contrib/chat/test/common/widget/annotations.test.ts | Adds regression coverage ensuring invalid tag content returns undefined instead of throwing. |
Copilot's findings
- Files reviewed: 2/2 changed files
- Comments generated: 0
d22f450 to
c2c9ea1
Compare
c2c9ea1 to
0d24661
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes a crash in VS Code’s chat rendering pipeline caused by invalid <vscode_codeblock_uri> tag contents (e.g. LLM-produced literals that aren’t parseable URIs), and tightens annotation detection to reduce false positives from code examples.
Changes:
- Anchor
<vscode_codeblock_uri>extraction to end-of-text and guardURI.parse(...)with try/catch to avoid renderer crashes on invalid URIs. - Update
hasCodeblockUriTag/hasEditCodeblockUriTagto ignore tags that occur inside complete fenced code blocks. - Add/extend unit tests covering invalid URI content, end-anchored matching, and fenced-code-block filtering.
Show a summary per file
| File | Description |
|---|---|
| src/vs/workbench/contrib/chat/common/widget/annotations.ts | Adds end-anchored extraction + URI.parse error handling; updates tag-detection helpers to strip complete fenced blocks first. |
| src/vs/workbench/contrib/chat/test/common/widget/annotations.test.ts | Adds regression tests for invalid URI/tag placement and for tag detection behavior around fenced code blocks. |
Copilot's findings
Comments suppressed due to low confidence (2)
src/vs/workbench/contrib/chat/common/widget/annotations.ts:273
- stripCompleteFencedCodeBlocks only matches fences that start at column 0 (
^({3,}|~{3,})`). In CommonMark (and in this repo’s markdown parsing/tests), fenced code blocks can be indented (e.g. inside list items with up to 3 leading spaces), so tags inside indented fences will not be stripped and hasCodeblockUriTag/hasEditCodeblockUriTag can still return true for LLM-generated code examples. Consider allowing optional leading whitespace on both opening/closing fence lines (or reusing the existing fence-scanning logic from isInsideCodeContext).
while ((match = /<vscode_annotation details='(.*?)'>(.*?)<\/vscode_annotation>/ms.exec(newText)) !== null) {
const [full, details, content] = match;
const start = match.index;
const textBefore = newText.substring(0, start);
const linesBefore = textBefore.split('\n').length - 1;
const linesInside = content.split('\n').length - 1;
const previousNewlineIdx = textBefore.lastIndexOf('\n');
src/vs/workbench/contrib/chat/test/common/widget/annotations.test.ts:379
- The new hasEditCodeblockUriTag/hasCodeblockUriTag behavior is only tested with non-indented fenced blocks. Since fenced blocks can be indented (e.g. within lists), it would be good to add a test case with leading spaces before the opening/closing fences to ensure stripCompleteFencedCodeBlocks actually ignores tags inside those code examples.
- Files reviewed: 2/2 changed files
- Comments generated: 0 new
When an LLM explains code that uses vscode_codeblock_uri tags, the literal tag content may not be a valid URI, causing URI.parse to throw and crash the chat renderer. Add try-catch around URI.parse so invalid content gracefully returns undefined, which callers already handle by falling back to normal code block rendering. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
0d24661 to
d56d15f
Compare
…validation error Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
DonJayamanne
approved these changes
Apr 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes a crash in the chat renderer when an LLM response contains a literal
<vscode_codeblock_uri>tag with non-URI content (e.g. backtick-fenced code blocks).Problem
When a Copilot agent discusses VS Code's own chat annotation code, it may include a literal
<vscode_codeblock_uri>XML tag in its markdown response. The regex inextractCodeblockUrisFromTextmatches the tag and passes the inner content toURI.parse(). When that content starts with a backtick or other illegal URI scheme character,URI.parsethrows aUriErrorthat propagates up throughtrackToolMetadata→appendItem→renderMarkdown→renderChatContentPart, crashing the chat list renderer.Fix
Wrap the
URI.parse(uriString)call in a try-catch that returnsundefinedon failure. All callers already handleundefinedgracefully:trackToolMetadata(thinking header): Falls to the else branch → shows "Edited file" labelchatMarkdownContentPart(code block rendering):codemapperUristaysundefined→ renders as a normal code block instead of an edit pillAdded a test case for the invalid URI scenario.
Fix #309299