dotnet/runtime · error · Error

Unknown object id

Error message

Unknown object id ${objId}

What it means

Thrown by `mono_wasm_call_function_on` when the requested `objectId` starts with `dotnet:cfo_res:` but is not present in the in-memory `_call_function_res_cache`. Each call-function-on result that returns an object/array is cached under a generated id; using an id after it was cleared (or that was never issued) is rejected because the proxy cannot reconstruct the underlying object.

Solutions

  1. Treat any runtime re-init (re-run of `mono_wasm_runtime_ready`) as invalidating all `dotnet:cfo_res:` ids; re-fetch them.
  2. Avoid persisting object ids across DevTools sessions; refresh the inspector tree after a reload.
  3. If you cache ids in client code, clear that cache when the runtime reloads.

Example fix

// before: id cached across a runtime restart
const id = previousResult.objectId; // 'dotnet:cfo_res:3'
await restartRuntime();
mono_wasm_call_function_on({ objectId: id, ... }); // throws

// after: re-acquire the id after restart
const id = (await mono_wasm_call_function_on({ objectId: rootId, ... })).objectId;
mono_wasm_call_function_on({ objectId: id, ... });
Defensive patterns

Strategy: validation

Validate before calling

function isCachedCfoId (objId) {
  return typeof objId === 'string' && objId.startsWith('dotnet:cfo_res:') && objId in _call_function_res_cache_pub;
}
if (isCachedCfoId(id)) mono_wasm_call_function_on({ objectId: id, ... });

Type guard

function isLiveCfoId (objId: string, cache: Record<string, unknown>): boolean {
  return objId.startsWith('dotnet:cfo_res:') && Object.prototype.hasOwnProperty.call(cache, objId);
}

Try / catch

try {
  return mono_wasm_call_function_on(request);
} catch (e) {
  if (e instanceof Error && /Unknown object id/.test(e.message)) {
    // re-acquire the object id from its root and retry once
    const fresh = await mono_wasm_call_function_on({ objectId: rootId, functionDeclaration: 'fn', arguments: [] });
    return mono_wasm_call_function_on({ ...request, objectId: fresh.objectId });
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling `mono_wasm_call_function_on` (debug.ts:224) with an `objectId` shaped `dotnet:cfo_res:<n>` whose key is not in `_call_function_res_cache`. Happens when the cache was reset by `mono_wasm_runtime_ready` (which clears it), when the id came from a stale DevTools session, or when the caller fabricated the id.

Common situations: DevTools inspector reusing an object reference across a runtime restart; long-lived page that re-initialises the runtime; passing an id obtained from a different tab/runtime instance.

Related errors


AI-assisted analysis of dotnet/runtime@60108ba66e (2026-08-10). Data as JSON: /api/errors/ed120a5a13588f4b. Report an issue: GitHub.

Appendix: source

Thrown at src/mono/browser/runtime/debug.ts:238

    });
    return proxy;
}

export function mono_wasm_call_function_on (request: CallRequest): CFOResponse {
    forceThreadMemoryViewRefresh();

    if (request.arguments != undefined && !Array.isArray(request.arguments))
        throw new Error(`"arguments" should be an array, but was ${request.arguments}`);

    const objId = request.objectId;
    const details = request.details;
    let proxy: any = {};

    if (objId.startsWith("dotnet:cfo_res:")) {
        if (objId in _call_function_res_cache)
            proxy = _call_function_res_cache[objId];
        else
            throw new Error(`Unknown object id ${objId}`);
    } else {
        proxy = _create_proxy_from_object_id(objId, details);
    }

    const fn_args = request.arguments != undefined ? request.arguments.map(a => JSON.stringify(a.value)) : [];

    const fn_body_template = `const fn = ${request.functionDeclaration}; return fn.apply(proxy, [${fn_args}]);`;
    const fn_defn = new Function("proxy", fn_body_template);
    const fn_res = fn_defn(proxy);

    if (fn_res === undefined)
        return { type: "undefined" };

    if (Object(fn_res) !== fn_res) {
        if (typeof (fn_res) == "object" && fn_res == null)
            return { type: typeof (fn_res), subtype: `${fn_res}`, value: null };
        return { type: typeof (fn_res), description: `${fn_res}`, value: `${fn_res}` };
    }

View on GitHub (pinned to 60108ba66e)