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
- Treat any runtime re-init (re-run of `mono_wasm_runtime_ready`) as invalidating all `dotnet:cfo_res:` ids; re-fetch them.
- Avoid persisting object ids across DevTools sessions; refresh the inspector tree after a reload.
- 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
- Invalidate cached ids when the runtime re-initialises (listen for runtime-ready).
- Refresh inspector trees after page reload instead of keeping stale references.
- Never fabricate `dotnet:cfo_res:` ids; only use ids returned by prior calls.
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
- Could not find any object with id
- "arguments" should be an array, but was
- args must be an object, but got
- Diag module already loaded
- event.eventName is a required parameter, in event
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)