'No handler found on any channel for message
I am a total noob and have been trying to get VSTS Work Item Field values into my VSTS Extension and have been hitting an issue. Whenever I load my extension in my browser this is the following error message that I am getting:
No handler found on any channel for message: {"id":2,"methodName":null,"instanceId":"sample-extension-page","instanceContext":{[RETRACTED]},"params":null,"jsonrpc":"2.0"}
I have scoured the internet and have not been able to find out what my issue is. I just want to pass in my active Work Item field values for System.Id and System.Title so I can display them on my extension page/form. Any help would be appreciated, thanks!
Script in my html page:
<script type="text/javascript">
console.log("VSS Initialize...");
VSS.init({
usePlatformScripts: true,
explicitNotifyLoaded: true,
usePlatformStyles: true,
configureModuleLoader:true
});
console.log("VSS Ready.");
VSS.ready(function(){
console.log("VSS REQUIRE");
VSS.require(["TFS/WorkItemTracking/Services"], function(_WorkItemServices) {
console.log("Inside VSS REQUIRE.");
// Get the WorkItemFormService. This service allows you to get/set fields/links on the 'active' work item (the work item
// that currently is displayed in the UI).
console.log("GET WORK ITEM FORM SERVICE");
function getWorkItemFormService(){
console.log("Inside GET WORK ITEM FORM SERVICE!");
return _WorkItemServices.WorkItemFormService.getService();
}
// VSS.register(VSS.getContribution().id, function(){
console.log("VSS REGISTER.");
console.log("VSS Contribution ID === " + VSS.getContribution().id);
VSS.register(VSS.getContribution().id, function(){
console.log("Inside VSS REGISTER");
return {
// Called when the active work item is modified
onFieldChanged: function(args) {
$(".events").append($("<div/>").text("onFieldChanged - " + JSON.stringify(args)));
},
// Called when a new work item is being loaded in the UI
onLoaded: function(args){
console.log("onloaded");
getWorkItemFormService().then(function(service) {
service.getFieldValues(["System.Id","System.Title"]).then(function(value){
$(".events").append($("<div/>").text("onLoaded - " + JSON.stringify(value)));
console.log("WORK ITEM VALUES : " + JSON.stringify(value));
});
});
},
// Called when the active work item is being unloaded in the UI
onUnloaded: function(args) {
console.log("onunloaded.");
$(".events").empty();
$(".events").append($("<div/>").text("onUnloaded - " + JSON.stringify(args)));
},
// Called after the work item has been saved
onSaved: function (args) {
$(".events").append($("<div/>").text("onSaved - " + JSON.stringify(args)));
},
// Called when the work item is reset to its unmodified state (undo)
onReset: function (args) {
$(".events").append($("<div/>").text("onReset - " + JSON.stringify(args)));
},
// Called when the work item has been refreshed from the server
onRefreshed: function (args) {
$(".events").append($("<div/>").text("onRefreshed - " + JSON.stringify(args)));
}
}
});
});
});
vss-extension.json file:
{
"manifestVersion": 1,
"id": "sample-extension",
"version": "0.1.64",
"name": "sampleextension",
"displayName":"Sample Extension",
"description": "Sample Extension",
"publisher": "[RETRACTED]",
"contentType":"application/json",
"targets": [
{
"id": "Microsoft.VisualStudio.Services"
}
],
"icons": {
"default": "images/icon.png"
},
"contributions": [
{
"id": "sample-extension-page",
"type": "ms.vss-work-web.work-item-form-page",
"description": "Sample extenion page",
"targets": [
"ms.vss-work-web.work-item-form"
],
"properties": {
"name": "sample-extenion-page",
"uri": "hello-world.html"
}
}
],
"scopes": [
"vso.work"
],
"files": [
{
"path": "scripts", "addressable": true
},
{
"path": "sdk/scripts", "addressable": true
},
{
"path": "images/icon.png", "addressable": true
},
{
"path":"hello-world.html","addressable":true
}
]
}
Solution 1:[1]
I had a similar issue... But it was user error. I was registering this on my configuration page:
VSS.register("HelloWorldWidget.Configuration", function () {
And then in my manifest I had:
{
"id": "TestWaffleWidget.Configuration",
"type": "ms.vss-dashboards-web.widget-configuration",
"targets": [ "ms.vss-dashboards-web.widget-configuration" ],
"properties": {
"name": "HelloWorldWidget Configuration",
"description": "Configures HelloWorldWidget",
"uri": "configuration.html"
}
}
This doesn't reconcile ("HelloWorldWidget.Configuration" and "TestWaffleWidget.Configuration" don't match) and then throws the "No handler found on any channel for message" error.
It looks like you might be falling into the same issue. You're registering:
VSS.register(VSS.getContribution().id, function(){
But unless VSS.getContribution().id matches "sample-extension-page" from your manifest, it's going to throw the no handler error.
Solution 2:[2]
have you set explicitNotifyLoaded to true? With this setup the error does not show for me:
VSS.init({
explicitNotifyLoaded: true,
usePlatformScripts: true
});
VSS.ready(function () {
VSS.register(VSS.getContribution().id, function (context) {
return {
// ...
};
});
VSS.notifyLoadSucceeded();
});
Solution 3:[3]
This issue happened to me just now.
I found that the reason was that explicitNotifyLoaded was not set.
The following worked for me:
- Set
explicitNotifyLoadedtotrue - Ensured the
instanceIdmatched thecontribution id. - Ensured I called
VSS.notifyLoadSucceeded()after the call toVSS.registerinside of the callback ofVSS.require()
Another point, the contributionId is not VSS.getContribution().id since that will return {provider}.{extensionid}.{contribution id}. You only need the contribution id.
AnnotationStatusWidget.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="../lib/VSS.SDK.min.js"></script>
</head>
<body>
<div class="widget">
<div id="root"></div>
</div>
<script type="text/javascript" src="AnnotationStatusWidget.js" charset="utf-8"></script>
</body>
</html>
AnnotationStatusWidget.tsx
import wh from "TFS/Dashboards/WidgetHelpers"
import {WidgetSettings} from "TFS/Dashboards/WidgetContracts"
import { showRootComponent } from "../../Common";
import * as React from "react";
const AnnotationStatusWidget : React.FunctionComponent<{}> = ({}) => {
const [isValidationOpened, setIsValidationOpened] = React.useState<boolean>(false);
return <>Hello World</>
}
// Initialize the VSS sdk
VSS.init({
usePlatformScripts: true,
usePlatformStyles: true,
explicitNotifyLoaded: true
});
VSS.ready(() => {
VSS.require(["TFS/Dashboards/WidgetHelpers"], function (WidgetHelpers: typeof wh) {
WidgetHelpers.IncludeWidgetStyles();
VSS.register("AnnotationStatusWidget", function () {
var projectId = VSS.getWebContext().project.id;
return {
load: async (widgetSettings: WidgetSettings) => {
showRootComponent(<AnnotationStatusWidget/>);
return await WidgetHelpers.WidgetStatusHelper.Success();
}
}
});
VSS.notifyLoadSucceeded();
});
})
vss-extension.json
{
...
"contributions": [
{
"id": "AnnotationStatusWidget",
"type": "ms.vss-dashboards-web.widget",
"targets": [
"ms.vss-dashboards-web.widget-catalog"
],
"properties": {
"name": "Hello World Widget",
"description": "My first widget",
"catalogIconUrl": "pipeline-run-annotation-widgets/img/CatalogIcon.png",
"previewImageUrl": "pipeline-run-annotation-widgets/img/preview.png",
"uri": "pipeline-run-annotation-widgets/dist/AnnotationStatusWidget/AnnotationStatusWidget.html",
"supportedSizes": [
{
"rowSpan": 1,
"columnSpan": 2
}
],
"supportedScopes": ["project_team"]
}
}
],
"scopes": ["vso.work"]
}
Solution 4:[4]
You need to call VSS.notifyLoadSucceeded() function after VSS.register() function (inside of VSS.require() function).
Solution 5:[5]
I'm a big noob here too, and I also spent a lot of time on this. I followed carefully examples from https://github.com/microsoft/vsts-extension-samples/tree/master/work-item-form and in my case the problem was referring to full ID.
In sample workItemToolbarButton.html file you have:
// Register a listener for the menu item contribution
VSS.register("Fabrikam.samples-work-item-form.sample-work-item-menu", function (context) {
return {
// Called when the menu item is clicked.
execute: function(actionContext) {
window.alert("Total fields changed: " + changedFieldCount[actionContext.workItemId]);
}
}
});
After removing this part, it worked immediately (I don't know why...):
VSS.register("Fabrikam.samples-work-item-form.sample-work-item-menu", function (context) {
Note: I thoroughly checked ID spelling many times, before trying this and that still didn't help.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Dileep Kumar |
| Solution 3 | |
| Solution 4 | starian chen-MSFT |
| Solution 5 | Krystian |
