MotionGPU normalizes all runtime errors into a consistent
MotionGPUErrorReportError normalization pipeline
All errors from initialization and per-frame rendering are processed by
toMotionGPUErrorReport(error, phase)| Phase | When |
|---|---|
'initialization' | WebGPU adapter/device acquisition, shader compilation, pipeline creation |
'render' | Per-frame render execution, texture uploads, buffer writes |
The function inspects the error message, classifies it into a category, and produces a structured report.
MotionGPUErrorReport shape
interface MotionGPUErrorReport {
title: string;
message: string;
hint: string;
details: string[];
stack: string[];
rawMessage: string;
phase: 'initialization' | 'render';
source: {
component: string;
location: string;
line: number;
column?: number;
snippet: Array<{
number: number;
code: string;
highlight: boolean;
}>;
} | null;
}interface MotionGPUErrorReport {
title: string;
message: string;
hint: string;
details: string[];
stack: string[];
rawMessage: string;
phase: 'initialization' | 'render';
source: {
component: string;
location: string;
line: number;
column?: number;
snippet: Array<{
number: number;
code: string;
highlight: boolean;
}>;
} | null;
}This interface describes the runtime callback payload shape used by
onErrorerrorRenderer| Field | Description |
|---|---|
title | Short category heading (e.g., "WGSL compilation failed" |
message | Primary human-readable error message |
hint | Suggested remediation or next step |
details | Additional lines (e.g., extra compiler messages) |
stack | Stack trace lines when available |
rawMessage | Original unsanitized error message |
phase | 'initialization''render' |
source | Structured source context for shader compile errors, or null |
Built-in classification patterns
The normalizer matches error messages against known patterns and assigns appropriate titles and hints:
| Pattern detected in message | Title | Hint |
|---|---|---|
WebGPU is not available in this browser | WebGPU unavailable | Use a browser with WebGPU enabled (latest Chrome/Edge/Safari TP) and secure context. |
Unable to acquire WebGPU adapter | WebGPU adapter unavailable | GPU adapter request failed. Check browser permissions, flags and device support. |
Canvas does not support webgpu context | Canvas cannot create WebGPU context | Make sure this canvas is attached to DOM and not using an unsupported context option. |
WGSL compilation failed | WGSL compilation failed | Check WGSL line numbers below and verify struct/binding/function signatures. |
WebGPU device lostDevice Lost | WebGPU device lost | GPU device/context was lost. Recreate the renderer and check OS/GPU stability. |
WebGPU uncaptured error | WebGPU uncaptured error | A GPU command failed asynchronously. Review details and validate resource/state usage. |
CreateBindGroupbind group layout | Bind group mismatch | Bindings in shader and runtime resources are out of sync. Verify uniforms/textures layout. |
Destination texture needs to have CopyDst | Invalid texture usage flags | Texture used as upload destination must include CopyDst (and often RenderAttachment). |
| (fallback) | MotionGPU render error | Review technical details below. If issue persists, isolate shader/uniform/texture changes. |
Overlay behaviour
By default,
FragCanvasMotionGPUErrorOverlay.sveltePortal.svelte| Prop | Default | Effect |
|---|---|---|
showErrorOverlay | true | Enables all error UI rendering |
errorRenderer | undefined | Optional custom renderer snippet that replaces the default overlay UI |
onError | undefined | Callback invoked with the normalized report |
Key behaviours
- Even when is
showErrorOverlay,falseis still called.onError - With set and
errorRenderer, custom UI is rendered instead of the default overlay.showErrorOverlay=true - The default overlay renders above canvas content using a DOM portal.
- Multiple errors display the most recent one.
Minimal error handling
<FragCanvas
{material}
onError={(report) => {
console.error(`[${report.phase}] ${report.title}: ${report.message}`);
if (report.hint) console.info(`Hint: ${report.hint}`);
}}
showErrorOverlay={false}
/><FragCanvas
{material}
onError={(report) => {
console.error(`[${report.phase}] ${report.title}: ${report.message}`);
if (report.hint) console.info(`Hint: ${report.hint}`);
}}
showErrorOverlay={false}
/>Custom error renderer
{#snippet myErrorRenderer(report)}
<aside class="error-banner">
<strong>{report.title}</strong>
<p>{report.message}</p>
</aside>
{/snippet}
<FragCanvas
{material}
errorRenderer={myErrorRenderer}
onError={(report) => {
console.error(report);
}}
/>{#snippet myErrorRenderer(report)}
<aside class="error-banner">
<strong>{report.title}</strong>
<p>{report.message}</p>
</aside>
{/snippet}
<FragCanvas
{material}
errorRenderer={myErrorRenderer}
onError={(report) => {
console.error(report);
}}
/>Shader compile diagnostics
When WGSL compilation fails, the renderer extracts diagnostics from
GPUShaderModule.getCompilationInfo()Source location mapping
The line map tracks which generated WGSL line corresponds to which original source:
| Map entry type | Reported as |
|---|---|
| User fragment | fragment line X |
| Include chunk | include <name> line X |
| Define constant | define "NAME" line X |
Structured diagnostics payload
For WGSL compilation failures, the error carries a structured diagnostics payload:
interface ShaderCompilationDiagnostic {
generatedLine: number;
message: string;
linePos?: number;
lineLength?: number;
sourceLocation: { kind: 'fragment' | 'include' | 'define'; line: number } | null;
}interface ShaderCompilationDiagnostic {
generatedLine: number;
message: string;
linePos?: number;
lineLength?: number;
sourceLocation: { kind: 'fragment' | 'include' | 'define'; line: number } | null;
}interface ShaderCompilationDiagnosticsPayload {
diagnostics: ShaderCompilationDiagnostic[];
fragmentSource: string;
includeSources: Record<string, string>;
defineBlockSource?: string;
}interface ShaderCompilationDiagnosticsPayload {
diagnostics: ShaderCompilationDiagnostic[];
fragmentSource: string;
includeSources: Record<string, string>;
defineBlockSource?: string;
}toMotionGPUErrorReport- — first compiler error enriched with source label and generated-line context (when available).
message - — additional compiler messages with the same contextual labels.
details - — component location, line number, and highlighted code snippet.
source
Overlay Source panel
When
report.source- Active source tab: source label + location metadata (fragment/include/define), with optional column.
- Source snippet centred around the failing line
- Highlighted failing line
- Additional diagnostics in a collapsible section
Device loss and uncaptured errors
The renderer listens for two asynchronous error conditions:
| Event | Source |
|---|---|
device.lost | GPU device lost (driver crash, system sleep, resource exhaustion) |
uncapturederror | Unexpected WebGPU validation or out-of-memory error |
Once captured, the error state is stored. The next render call throws a normalized error so
FragCanvasRetry strategy
When renderer creation fails,
FragCanvas| Attempt | Delay |
|---|---|
| 1st retry | 250 ms |
| 2nd retry | 500 ms |
| 3rd retry | 1000 ms |
| 4th retry | 2000 ms |
| 5th retry | 4000 ms |
| 6th+ retry | 8000 ms (cap) |
Retry state resets when the pipeline signature changes (e.g., when you fix a shader error and hot-reload).
Production recommendations
- Always provide — send reports to your logging/telemetry system.
onError - Keep default overlay enabled in dev/staging — it surfaces WGSL errors with line-level precision.
- Use in production when you need branded/error-system-integrated UI.
errorRenderer - Surface and
phaseprominently in alerting — they are the most actionable fields.title - Use for contextual guidance — each error classification provides a specific suggestion.
hint