dotnet/runtime · error · Error
not found while looking up
Error message
${part} not found while looking up ${function_name} What it means
Thrown by mono_wasm_lookup_js_import in invoke-js.ts while walking the dotted path of a [JSImport] function name (e.g. MyNs.SubNs.method). It iterates all parts except the last, descending the scope chain; if any intermediate property is missing it throws with the offending part and the full function name. This means the JS object graph does not match the managed import attribute.
Solutions
- Verify the dotted path in [DllImport]/[JSImport] matches the actual JS object graph (log the scope at each step).
- Ensure the containing JS module was imported via JSHost.ImportAsync before the JSImport is invoked (threads).
- Fix typos in the namespace segments.
Example fix
// before: [JSImport("MyApp.Utilz.parse")] but Utilz is named Utils
// after:
[JSImport("MyApp.Utils.parse")] static partial int Parse(); Defensive patterns
Strategy: validation
Validate before calling
// validate the dotted path resolves before the JSImport is bound
function resolvePath(root: any, dotted: string): boolean {
let scope = root;
for (const part of dotted.split('.').slice(0, -1)) {
if (scope == null || !(part in scope)) return false;
scope = scope[part];
}
return scope != null;
} Type guard
function isResolvableNamespace(root: any, dotted: string): boolean {
let scope = root;
for (const part of dotted.split('.')) {
if (scope == null || typeof scope !== 'object') return false;
scope = scope[part];
}
return true;
} Prevention
- Keep [JSImport] paths in sync with the JS module's export shape.
- When using threads, call JSHost.ImportAsync on the UI/worker thread before invoking.
- Unit-test namespace resolution against the real JS module.
When it happens
Trigger: A [JSImport("A.B.foo")] where A exists but A.B is undefined; importing from a module object that has not been fully populated; a typo in the dotted path; the JSExport/globalThis target object was reshaped.
Common situations: Renaming a JS namespace without updating the [JSImport] attribute; importing before the JS module that defines the namespace has loaded (with threads, before JSHost.ImportAsync on the UI/worker thread).
Related errors
- must be a Function but was
- must be a Function but was
- not found while looking up
- Argument to stringToInternedMonoStringRoot must be a string…
- Cannot call synchronous C# method from inside a synchronous…
AI-assisted analysis of dotnet/runtime@60108ba66e (2026-08-10).
Data as JSON: /api/errors/9b7dcebd9d58a96f.
Report an issue: GitHub.
Appendix: source
Thrown at src/mono/browser/runtime/invoke-js.ts:404
scope = importedModules.get(js_module_name);
if (WasmEnableThreads) {
mono_assert(scope, () => `ES6 module ${js_module_name} was not imported yet, please call JSHost.ImportAsync() on the UI or JSWebWorker thread first in order to invoke ${function_name}.`);
} else {
mono_assert(scope, () => `ES6 module ${js_module_name} was not imported yet, please call JSHost.ImportAsync() first in order to invoke ${function_name}.`);
}
} else if (parts[0] === "INTERNAL") {
scope = 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 ${function_name}`);
}
scope = newscope;
}
const fname = parts[parts.length - 1];
const fn = scope[fname];
if (typeof (fn) !== "function") {
throw new Error(`${function_name} 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 set_property (self: any, name: string, value: any): void {
mono_check(self, "Null reference");
self[name] = value;View on GitHub (pinned to 60108ba66e)