dotnet/aspnetcore · error
The value '${identifier}' is not a function.
Error message
The value '${identifier}' is not a function. What it means
Thrown by wrapJSCallAsFunction for JSCallType.FunctionCall: the member resolved from the identifier exists but is not an instance of Function. The framework calls func.bind(parent) and invokes it; a non-callable value (number, object, getter that returns a non-function) cannot be invoked.
Source
Thrown at src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts:629
];
}
// Takes an object member and a call type and returns a function that performs the operation specified by the call type on the member.
//
// @param parent Immediate parent of the accessed object member.
// @param memberName Name (key) of the accessed member.
// @param callType The type of the operation to perform on the member.
// @param identifier The full member identifier. Only used for error messages.
// @returns A function that performs the operation on the member.
//
function wrapJSCallAsFunction(parent: any, memberName: string, callType: JSCallType, identifier: string): Function {
switch (callType) {
case JSCallType.FunctionCall:
const func = parent[memberName];
if (func instanceof Function) {
return func.bind(parent);
}
throw new Error(`The value '${identifier}' is not a function.`);
case JSCallType.ConstructorCall:
const ctor = parent[memberName];
if (ctor instanceof Function) {
const bound = ctor.bind(parent);
return (...args: any[]) => new bound(...args);
}
throw new Error(`The value '${identifier}' is not a function.`);
case JSCallType.GetValue:
if (!isReadableProperty(parent, memberName)) {
throw new Error(`The property '${identifier}' is not defined or is not readable.`);
}
return () => parent[memberName];
case JSCallType.SetValue:
if (!isWritableProperty(parent, memberName)) {
throw new Error(`The property '${identifier}' is not writable.`);
}View on GitHub (pinned to 294cab2f9b)
Solutions
- Check the JS exports: ensure the identifier points to a function (typeof x === 'function').
- Rename so the function and the data property do not collide.
- If you meant to read a value, use the read/get path instead of the call path on the .NET side.
- Add a thin wrapper function in JS that returns the value.
Example fix
// before
// lib.js
export const count = 0; // data, not fn
// C#: await JS.InvokeAsync<int>("lib.count");
// after
// lib.js
export function getCount() { return 0; }
// C#: await JS.InvokeAsync<int>("lib.getCount"); Defensive patterns
Strategy: type-guard
Validate before calling
// shim: assert callable before exposing
export function ensureFn(obj, id) {
const fn = id.split('.').reduce((o,k)=>o?.[k], obj);
if (typeof fn !== 'function') throw new TypeError(`${id} is not a function`);
return fn;
} Type guard
function isCallable(v: any): v is Function { return typeof v === 'function'; } Try / catch
try { await JS.InvokeAsync('lib.fn'); } catch (e) { if (/is not a function/i.test(e.message)) { /* fix identifier */ } else throw e; } Prevention
- Audit JS exports: each invoked identifier must be a function.
- Avoid name collisions between data and function exports.
- Add unit tests asserting typeof === 'function' on exported members.
When it happens
Trigger: Calling .invokeMethod('myLib.value') where 'value' is a property holding data, not a function; invoking a getter; calling a key that holds an object/array. Distinguish from error 84 (missing) — here the member exists but is not callable.
Common situations: Naming collision between a data property and the function you meant to call; refactor that turned a function into a property; calling a namespace object as if it were a function.
Related errors
- Cannot create a JSObjectReference from the value '${jsObject
- Cannot create a JSStreamReference from the value '${streamRe
- Supplied value is not a typed array or blob.
- Cannot create a JSStreamReference from the value '${streamRe
- No call dispatcher has been set.
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/47ba4c4bce82054f.
Report an issue: GitHub.