{"record":{"id":"91621728fe81fe1b","repo":"SignalR/SignalR","slug":"the-binding-bindingname-cannot-be-used-wit","errorCode":null,"errorMessage":"The binding ' + bindingName + ' cannot be used with virtual elements","messagePattern":"The binding ' \\+ bindingName \\+ ' cannot be used with virtual elements","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"samples/Microsoft.AspNet.SignalR.LoadTestHarness/Scripts/knockout-2.1.0.debug.js","lineNumber":1891,"sourceCode":"            this['$parents'].unshift(this['$parent']);\n        } else {\n            this['$parents'] = [];\n            this['$root'] = dataItem;\n        }\n        this['$data'] = dataItem;\n    }\n    ko.bindingContext.prototype['createChildContext'] = function (dataItem) {\n        return new ko.bindingContext(dataItem, this);\n    };\n    ko.bindingContext.prototype['extend'] = function(properties) {\n        var clone = ko.utils.extend(new ko.bindingContext(), this);\n        return ko.utils.extend(clone, properties);\n    };\n\n    function validateThatBindingIsAllowedForVirtualElements(bindingName) {\n        var validator = ko.virtualElements.allowedBindings[bindingName];\n        if (!validator)\n            throw new Error(\"The binding '\" + bindingName + \"' cannot be used with virtual elements\")\n    }\n\n    function applyBindingsToDescendantsInternal (viewModel, elementOrVirtualElement, bindingContextsMayDifferFromDomParentElement) {\n        var currentChild, nextInQueue = ko.virtualElements.firstChild(elementOrVirtualElement);\n        while (currentChild = nextInQueue) {\n            // Keep a record of the next child *before* applying bindings, in case the binding removes the current child from its position\n            nextInQueue = ko.virtualElements.nextSibling(currentChild);\n            applyBindingsToNodeAndDescendantsInternal(viewModel, currentChild, bindingContextsMayDifferFromDomParentElement);\n        }\n    }\n\n    function applyBindingsToNodeAndDescendantsInternal (viewModel, nodeVerified, bindingContextMayDifferFromDomParentElement) {\n        var shouldBindDescendants = true;\n\n        // Perf optimisation: Apply bindings only if...\n        // (1) We need to store the binding context on this node (because it may differ from the DOM parent node's binding context)\n        //     Note that we can't store binding contexts on non-elements (e.g., text nodes), as IE doesn't allow expando properties for those\n        // (2) It might have bindings (e.g., it has a data-bind attribute, or it's a marker for a containerless template)","sourceCodeStart":1873,"sourceCodeEnd":1909,"githubUrl":"https://github.com/SignalR/SignalR/blob/693053b89a9e1f5ce819e3233ed159a6409de22b/samples/Microsoft.AspNet.SignalR.LoadTestHarness/Scripts/knockout-2.1.0.debug.js#L1873-L1909","documentation":"validateThatBindingIsAllowedForVirtualElements checks ko.virtualElements.allowedBindings for the binding name. If the binding is not registered there, it throws, because not all bindings can work with virtual (comment-based) elements — only those explicitly whitelisted. This prevents bindings that require a real DOM element from being applied to a comment node.","triggerScenarios":"Using a binding inside a virtual element (<!-- ko bindingName: ... -->) where bindingName is not registered in ko.virtualElements.allowedBindings. For example, using 'value' or 'checked' in a containerless binding, as these require a real form element. Only bindings like 'if', 'foreach', 'with', 'template' are typically whitelisted.","commonSituations":"A developer wraps a binding that needs a real element (like 'value', 'attr', 'css') in containerless comment syntax. Using a custom binding handler in a virtual element without registering it in ko.virtualElements.allowedBindings.","solutions":["Move the binding to a real DOM element instead of using containerless comment syntax.","If using a custom binding handler with virtual elements, register it: ko.virtualElements.allowedBindings['myBinding'] = true.","Only use containerless bindings for flow-control bindings explicitly designed for virtual elements."],"exampleFix":"<!-- before: 'value' not allowed in virtual element -->\n<!-- ko value: someProperty --><!-- /ko -->\n<!-- after: use a real input element -->\n<input data-bind='value: someProperty' />","handlingStrategy":"validation","validationCode":"// Check if a binding is allowed for virtual elements\nfunction isAllowedForVirtualElements(bindingName) {\n    return !!ko.virtualElements.allowedBindings[bindingName];\n}\n\n// Known allowed bindings in KO 2.1.0: if, ifnot, foreach, with, template\n// Before using a binding in containerless syntax:\nif (!isAllowedForVirtualElements('myCustomBinding')) {\n    console.warn('myCustomBinding cannot be used with <!-- ko --> virtual elements');\n}","typeGuard":null,"tryCatchPattern":"try {\n    ko.applyBindings(viewModel, element);\n} catch (e) {\n    if (e.message.indexOf('cannot be used with virtual elements') !== -1) {\n        console.error('This binding requires a real DOM element, not a virtual element:', e.message);\n    } else {\n        throw e;\n    }\n}","preventionTips":["Only use flow-control bindings (if, foreach, with, template) in containerless <!-- ko --> syntax.","For custom bindings that need virtual element support, register them: ko.virtualElements.allowedBindings['myBinding'] = true.","Move bindings that require real elements (value, checked, attr, css) to actual HTML elements.","Review Knockout documentation for which built-in bindings support virtual elements."],"tags":["knockout","virtual-elements","binding-handlers","validation"],"backgroundTag":null,"analyzedSha":"693053b89a9e1f5ce819e3233ed159a6409de22b","analyzedAt":"2026-08-13T22:23:59.793Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}