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

  1. Verify the dotted path in [DllImport]/[JSImport] matches the actual JS object graph (log the scope at each step).
  2. Ensure the containing JS module was imported via JSHost.ImportAsync before the JSImport is invoked (threads).
  3. 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

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


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)