dotnet/runtime · error · Error
${part} not found while looking up ${functionName}
Error message
${part} not found while looking up ${functionName} What it means
lookupJsImport walks the dotted function name (e.g. 'MyModule.Sub.Fn') through the imported JS module's scope; if any intermediate segment is undefined it throws, naming the missing part. This is the JSImport resolution path used by [JSImport] bindings after JSHost.ImportAsync has loaded the module.
Source
Thrown at src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/invoke-js.ts:286
let scope: any = {};
const parts = functionName.split(".");
if (jsModuleName) {
scope = importedModules.get(jsModuleName);
dotnetAssert.fastCheck(scope, () => `ES6 module ${jsModuleName} was not imported yet, please call JSHost.ImportAsync() first in order to invoke ${functionName}.`);
} else if (parts[0] === "INTERNAL") {
scope = dotnetApi.INTERNAL;
parts.shift();
} else if (parts[0] === "globalThis") {
scope = globalThis;
parts.shift();
}
for (let i = 0; i < parts.length - 1; i++) {
const part = parts[i];
const newscope = scope[part];
if (!newscope) {
throw new Error(`${part} not found while looking up ${functionName}`);
}
scope = newscope;
}
const fname = parts[parts.length - 1];
const fn = scope[fname];
if (typeof (fn) !== "function") {
throw new Error(`${functionName} must be a Function but was ${typeof fn}`);
}
// if the function was already bound to some object it would stay bound to original object. That's good.
return fn.bind(scope);
}
export function invokeJSFunction(functionJSHandle: JSHandle, args: JSMarshalerArguments): void {
assertRuntimeRunning();
const boundFn = getJSObjectFromJSHandle(functionJSHandle);View on GitHub (pinned to 290d5ab72c)
Solutions
- Call and await JSHost.ImportAsync(moduleName, url) before invoking any JSImport from that module.
- Verify the dotted name in [JSImport] matches the actual nested export path — log the imported module object to inspect its shape.
- Check for typos and casing in the function name and every intermediate segment.
Example fix
// before
[JSImport("Sub.Fn", "mod")] // 'Sub' missing on module -> "Sub not found while looking up Sub.Fn"
// after: import first, and match the export structure
await JSHost.ImportAsync("mod", "./mod.js");
// mod.js: export const Sub = { Fn: () => {} }; Defensive patterns
Strategy: validation
Validate before calling
function resolvePath(module, dotted) {
let scope = module;
const parts = dotted.split(".");
for (const part of parts.slice(0, -1)) {
if (scope == null || !(part in scope)) return false;
scope = scope[part];
}
return typeof scope[parts[parts.length - 1]] === "function";
}
if (!resolvePath(importedModule, "Sub.Fn")) { /* wrong path / not imported */ } Try / catch
// C# caller: lookupJsImport errors are marshaled to .NET as JSException
try { await jsImport.Fn(); }
catch (JSException ex) when (ex.Message.Contains("not found while looking up")) {
// module path wrong, not imported, or typo — fix the [JSImport] name / call ImportAsync
} Prevention
- Always ImportAsync a module before invoking any of its JSImports.
- Keep [JSImport] dotted names in sync with the JS export structure.
- Add a startup smoke test that imports each module and checks the expected export path exists.
When it happens
Trigger: A [JSImport('A.B.C', 'mod')] whose module object lacks the expected nested path — the module wasn't imported yet, the dotted name has a typo or wrong casing, or the JS export isn't nested where the binding expects.
Common situations: Forgetting to await JSHost.ImportAsync('mod', url) before invoking a JSImport; renaming/moving a JS export without updating the attribute; a mismatch between the module's real export shape and the dotted name; casing differences on case-sensitive hosts.
Related errors
- ${part} not found while looking up ${function_name}
- ${function_name} must be a Function but was ${typeof fn}
- ${functionName} must be a Function but was ${typeof fn}
- Cannot call synchronous C# methods.
- Cannot call synchronous C# method from inside a synchronous
AI-assisted analysis of dotnet/runtime@290d5ab72c (2026-08-06).
Data as JSON: /api/errors/7ffd2e2b32d3a7b1.
Report an issue: GitHub.