AvaloniaUI/Avalonia · error · Error
Unable to access .NET memory
Error message
Unable to access .NET memory
What it means
Thrown by SoftwareRenderTarget.putPixelData when the cached runtime's localHeapViewU8() (or its underlying ArrayBuffer) is unavailable. This view is the bridge into the .NET WASM linear memory used to copy frame pixels into an ImageData. Without it the renderer cannot read the framebuffer the managed side produced.
Source
Thrown at src/Browser/Avalonia.Browser/webapp/modules/avalonia/rendering/softwareRenderTarget.ts:35
this.runtime = globalThis.getDotnetRuntime(0);
}
public putPixelData(pointer: number, length: number, width: number, height: number): void {
const heap8 = this.runtime?.localHeapViewU8();
let clampedBuffer: Uint8ClampedArray;
if (heap8?.buffer) {
clampedBuffer = new Uint8ClampedArray(heap8.buffer, pointer, length);
// Need to make a copy if using MT, ImageData can't consume shared arrays
if (this.canvas instanceof OffscreenCanvas) {
const dstArrayBuffer = new ArrayBuffer(clampedBuffer.byteLength);
const copy = new Uint8ClampedArray(dstArrayBuffer);
copy.set(clampedBuffer);
clampedBuffer = copy;
}
} else throw new Error("Unable to access .NET memory");
const imageData = new ImageData(clampedBuffer, width, height);
(this.context).putImageData(imageData, 0, 0);
}
public static staticPutPixelData(target: SoftwareRenderTarget, pointer: number, length: number, width: number, height: number): void {
target.putPixelData(pointer, length, width, height);
}
}
View on GitHub (pinned to 11c5427268)
Solutions
- Defer rendering until the .NET runtime reports ready and getDotnetRuntime(0) is non-null.
- Re-fetch the heap view on every putPixelData call rather than relying on a stale reference.
- Stop the render loop on runtime disposal/dispose events before the next putPixelData.
- Guard the entry point: skip or reschedule the frame when this.runtime is undefined instead of throwing.
Example fix
// before
const heap8 = this.runtime?.localHeapViewU8();
if (heap8?.buffer) { ... } else throw new Error("Unable to access .NET memory");
// after
const runtime = globalThis.getDotnetRuntime(0);
const heap8 = runtime?.localHeapViewU8();
if (!heap8?.buffer) { return; /* skip frame, runtime not ready */ } Defensive patterns
Strategy: validation
Validate before calling
const runtime = globalThis.getDotnetRuntime?.(0);
const heap = runtime?.localHeapViewU8();
if (!runtime || !heap?.buffer) { /* skip frame, runtime not ready */ } Type guard
function hasDotnetMemory(rt: RuntimeAPI | undefined): boolean {
const heap = rt?.localHeapViewU8();
return !!heap && !!heap.buffer && heap.buffer.byteLength > 0;
} Try / catch
try { target.putPixelData(pointer, length, width, height); }
catch (e) {
if (e instanceof Error && e.message.includes('.NET memory')) { /* reschedule next frame */ return; }
throw e;
} Prevention
- Start the render loop only after the .NET runtime ready signal.
- Re-fetch localHeapViewU8 each frame instead of caching across memory growth.
- Stop rendering on runtime dispose.
When it happens
Trigger: putPixelData(pointer, length, width, height) is called when globalThis.getDotnetRuntime(0) returned undefined at construction time, the runtime was shut down/disposed, or localHeapViewU8() returned a value whose .buffer is falsy (detached/grown ArrayBuffer after memory growth).
Common situations: .NET WASM runtime not fully initialized before the first render tick; runtime disposed during navigation/reload; memory was grown (heap resized) invalidating a previously captured view; running the webapp outside the real Avalonia WASM host so getDotnetRuntime is undefined.
Related errors
- Module.GL object wasn't initialized, WebGL can't be used.
- Unable to access emscripten PThread api
- HTMLCanvasElement.getContext returned null.
- Unable get pthread with id ${pthreadId}
- Unable get Worker for pthread ${pthreadId}
AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13).
Data as JSON: /api/errors/b9b37e7fe99ad3d4.
Report an issue: GitHub.