Change:
I'm an extension author and frequently have issues open with generic titles ("Extension issue") and not enough information to do anything with (usually ending " We have written the needed data into your clipboard. Please paste! " or a similar message about attaching a file) (). I see VS Code gets many issues the same, and has a bot to close them. It seems unfortunate that users are taking time to come to GitHub and submit issues, but they often end up closed due to not having enough information. It's not clear to me what prompts users to create these issues, but perhaps there are ways that they could be improved. For example: populating the title with "Extension issue" makes it easy for a user to submit without entering a single word of text about the problem. If the field was left blank, they would not be able to submit the form without typing something that might give some indication of what prompted them to file the issue. perhaps GitHub could detect this string (or some variation of) and give the user a nudge that maybe they have forgotten to paste/attach something? (I know that's a request for GitHub, but they don't have a public issue tracker and perhaps this team has contacts there ) include some summary of the data in the clipboard in the originally message (I've no idea what it is, because I don't know if anybody has ever successfully pasted it).. querystrings can be fairly long these days even if the whole message can't be included
may also help reduce these.
Ah yes, that might help too. Out of interest, do you know what is prompting users to create these, and what sort of information is included in the clipboard? I'm not sure I've ever had anyone come back to me with the data (likely because their clipboard has been reused by the time they see my response) so I've zero ideas about what might be happening.
these are created by the Issue Reporter: ! ! The PR linked upped the max number of characters so we should see a lot less of those issues. That said, it is suspicious that they all have the title "Extension Issue"... makes me wonder if someone wrote a script of some kind to spam issues.
Hmm, that is odd - in your screenshot both the title and body are mandatory, but I get "Extension issue" so often from different peope, I'd be surprised if they were all typing it: !
coming from here maybe?
Nice find. Looks like that gets run from this page: ! Looks like a relic of the past... let me see what I can do here
Ok I have a PR out that will route that through the issue reporter instead.
neat, thanks!
this code does similar: is a recent example of an issue created that way but lacking the clipboard-pasted info.
Verification steps: Open Running Extensions Right click on an extension and click report issue The Issue reporter should open and not

Discussion:
const mainProcessService = new ElectronIPCMainProcessService(configuration.windowId); this.nativeHostService = new NativeHostService(configuration.windowId, mainProcessService) as INativeHostService; <del> const targetExtension = configuration.data.extensionId ? configuration.data.enabledExtensions.find(extension => extension.id === configuration.data.extensionId) : undefined; </del> <ins> const targetExtension = configuration.data.extensionId ? configuration.data.enabledExtensions.find(extension => extension.id.toLocaleLowerCase() === configuration.data.extensionId?.toLocaleLowerCase()) : undefined; </ins> this.issueReporterModel = new IssueReporterModel({ ...configuration.data, issueType: configuration.data.issueType || IssueType.Bug,

import { IExtensionHostProfile } from 'vs/workbench/services/extensions/common/extensions'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { AbstractRuntimeExtensionsEditor, IRuntimeExtension } from 'vs/workbench/contrib/extensions/browser/abstractRuntimeExtensionsEditor'; <ins> import { ReportExtensionIssueAction } from 'vs/workbench/contrib/extensions/common/reportExtensionIssueAction'; </ins> export class RuntimeExtensionsEditor extends AbstractRuntimeExtensionsEditor {

} protected _createReportExtensionIssueAction(element: IRuntimeExtension): Action | null { <ins> if (element.marketplaceInfo) { return this._instantiationService.createInstance(ReportExtensionIssueAction, element.description); } </ins> return null; }

<ins> /*--------------------------------------------------------------------------------------------- *  Copyright (c) Microsoft Corporation. All rights reserved. *  Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as nls from 'vs/nls'; import { Action } from 'vs/base/common/actions'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { IWorkbenchIssueService } from 'vs/workbench/services/issue/common/issue'; export class ReportExtensionIssueAction extends Action { private static readonly _id = 'workbench.extensions.action.reportExtensionIssue'; private static readonly _label = nls.localize('reportExtensionIssue', "Report Issue"); // TODO: Consider passing in IExtensionStatus or IExtensionHostProfile for additional data constructor( private extension: IExtensionDescription, @IWorkbenchIssueService private readonly issueService: IWorkbenchIssueService ) { super(ReportExtensionIssueAction._id, ReportExtensionIssueAction._label, 'extension-action report-issue'); this.enabled = extension.isBuiltin || (!!extension.repository && !!extension.repository.url); } override async run(): Promise<void> { await this.issueService.openReporter({ extensionId: this.extension.id, }); } } </ins>

<del> /*--------------------------------------------------------------------------------------------- *  Copyright (c) Microsoft Corporation. All rights reserved. *  Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as nls from 'vs/nls'; import { IProductService } from 'vs/platform/product/common/productService'; import { Action } from 'vs/base/common/actions'; import { IExtension } from 'vs/workbench/contrib/extensions/common/extensions'; import { IExtensionsStatus, IExtensionHostProfile } from 'vs/workbench/services/extensions/common/extensions'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { INativeHostService } from 'vs/platform/native/electron-sandbox/native'; import { ExtensionType, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { URI } from 'vs/base/common/uri'; const builtinExtensionIssueUrl = 'https://github.com/microsoft/vscode'; export class ReportExtensionIssueAction extends Action { private static readonly _id = 'workbench.extensions.action.reportExtensionIssue'; private static readonly _label = nls.localize('reportExtensionIssue', "Report Issue"); private _url: string | undefined; constructor( private extension: { description: IExtensionDescription; marketplaceInfo: IExtension; status?: IExtensionsStatus; unresponsiveProfile?: IExtensionHostProfile; }, @IOpenerService private readonly openerService: IOpenerService, @IClipboardService private readonly clipboardService: IClipboardService, @IProductService private readonly productService: IProductService, @INativeHostService private readonly nativeHostService: INativeHostService ) { super(ReportExtensionIssueAction._id, ReportExtensionIssueAction._label, 'extension-action report-issue'); this.enabled = extension.description.isBuiltin || (!!extension.description.repository && !!extension.description.repository.url); } override async run(): Promise<void> { if (!this._url) { this._url = await this._generateNewIssueUrl(this.extension); } this.openerService.open(URI.parse(this._url)); } private async _generateNewIssueUrl(extension: { description: IExtensionDescription; marketplaceInfo: IExtension; status?: IExtensionsStatus; unresponsiveProfile?: IExtensionHostProfile; }): Promise<string> { let baseUrl = extension.marketplaceInfo && extension.marketplaceInfo.type === ExtensionType.User && extension.description.repository ? extension.description.repository.url : undefined; if (!baseUrl && extension.description.isBuiltin) { baseUrl = builtinExtensionIssueUrl; } if (!!baseUrl) { baseUrl = `${baseUrl.indexOf('.git') !== -1 ? baseUrl.substr(0, baseUrl.length - 4) : baseUrl}/issues/new/`; } else { baseUrl = this.productService.reportIssueUrl!; } const reason = 'Bug'; const title = 'Extension issue'; const message = ':warning: We have written the needed data into your clipboard. Please paste! :warning:'; this.clipboardService.writeText('```json n' + JSON.stringify(extension.status, null, 't') + 'n```'); const os = await this.nativeHostService.getOSProperties(); const osVersion = `${os.type} ${os.arch} ${os.release}`; const queryStringPrefix = baseUrl.indexOf('?') === -1 ? '?' : '&'; const body = encodeURIComponent( `- Issue Type: `${reason}` - Extension Name: `${extension.description.name}` - Extension Version: `${extension.description.version}` - OS Version: `${osVersion}` - VS Code version: `${this.productService.version}`nn${message}` ); return `${baseUrl}${queryStringPrefix}body=${body}&title=${encodeURIComponent(title)}`; } } </del>

import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { SlowExtensionAction } from 'vs/workbench/contrib/extensions/electron-sandbox/extensionsSlowActions'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; <del> import { ReportExtensionIssueAction } from 'vs/workbench/contrib/extensions/electron-sandbox/reportExtensionIssueAction'; </del> <ins> import { ReportExtensionIssueAction } from 'vs/workbench/contrib/extensions/common/reportExtensionIssueAction'; </ins> import { AbstractRuntimeExtensionsEditor, IRuntimeExtension } from 'vs/workbench/contrib/extensions/browser/abstractRuntimeExtensionsEditor'; import { VSBuffer } from 'vs/base/common/buffer'; import { URI } from 'vs/base/common/uri';

protected _createReportExtensionIssueAction(element: IRuntimeExtension): Action | null { if (element.marketplaceInfo) { <del> return this._instantiationService.createInstance(ReportExtensionIssueAction, { description: element.description, marketplaceInfo: element.marketplaceInfo, status: element.status, unresponsiveProfile: element.unresponsiveProfile }); </del> <ins> return this._instantiationService.createInstance(ReportExtensionIssueAction, element.description); </ins> } return null; }