Advanced

Error Handling

Understanding the error normalization pipeline, structured reports, and diagnostics.


MotionGPU normalizes all runtime errors into a consistent

MotionGPUErrorReport
structure. This page covers the error pipeline, classification patterns, default/custom error UI behaviour, shader compile diagnostics, device loss handling, and retry strategy.

Error 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

onError
/
errorRenderer
.

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'
or
'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 lost
/
Device 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.
CreateBindGroup
/
bind 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,

FragCanvas
displays runtime errors through
MotionGPUErrorOverlay.svelte
(rendered via
Portal.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
    showErrorOverlay
    is
    false
    ,
    onError
    is still called.
  • With
    errorRenderer
    set and
    showErrorOverlay=true
    , custom UI is rendered instead of the default overlay.
  • 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()
and maps line numbers using the material’s source line map.

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
uses this to build:

  • message
    — first compiler error enriched with source label and generated-line context (when available).
  • details
    — additional compiler messages with the same contextual labels.
  • source
    — component location, line number, and highlighted code snippet.

Overlay Source panel

When

report.source
is available, the overlay shows:

  • 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
promise
GPU device lost (driver crash, system sleep, resource exhaustion)
uncapturederror
event
Unexpected WebGPU validation or out-of-memory error

Once captured, the error state is stored. The next render call throws a normalized error so

FragCanvas
can display it through the standard reporting path.

Retry strategy

When renderer creation fails,

FragCanvas
retries with exponential backoff:

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

  1. Always provide
    onError
    — send reports to your logging/telemetry system.
  2. Keep default overlay enabled in dev/staging — it surfaces WGSL errors with line-level precision.
  3. Use
    errorRenderer
    in production
    when you need branded/error-system-integrated UI.
  4. Surface
    phase
    and
    title
    prominently in alerting — they are the most actionable fields.
  5. Use
    hint
    for contextual guidance — each error classification provides a specific suggestion.