Troubleshooting
This content is for v0.4. Switch to the latest version for up-to-date documentation.
Find your symptom, then check the cause and the fix. Errors carry a code (GPU_INIT_FAILED, INVALID_INPUT, …): the browser engine and the native host share the engine’s codes, and the host protocol lists the rest. Validation and errors explains how to handle them in code.
Rendering and the GPU
Section titled “Rendering and the GPU”The canvas stays blank, or the engine fails with GPU_INIT_FAILED
Section titled “The canvas stays blank, or the engine fails with GPU_INIT_FAILED”Cause. The engine could not create a GPU device. In a browser that means no WebGPU and no WebGL2 (hardware acceleration is off, the GPU is blocklisted, or the page runs in a VM). On a server it means no GPU driver the host can use.
Fix.
- In the browser, let the engine fall back to the CPU renderer: the worker host’s
renderer: "auto"draws on the CPU when there is neither WebGPU nor WebGL2, and says which it made inrendererChoice.WebEffectRegistry.createCpu(canvas)makes the CPU renderer directly. It draws the same pixels, more slowly. - Natively,
alpha2-hostexits with status 70 onGPU_INIT_FAILED. Use--renderer auto(the default) or--renderer cpuon a machine without a GPU:--renderer gpufails when there is no adapter. - Check what the browser offers on Platform support.
The canvas is blank but there is no error
Section titled “The canvas is blank but there is no error”Cause. The engine has no frame for the sources the time shows. The application decodes media and uploads it; the engine draws only what it was given.
Fix. Read what renderAt(ticks) returns: missingSources and missingFrames name what it lacked. frameNeeds(ticks) lists the frames a time needs with their exact source times. Upload them (uploadVideoFrame, uploadRgbaFrame, uploadRgbaImage) and render again, or let FrameSupply from alpha2/frame-supply do it.
The export fails with GPU_DEVICE_LOST
Section titled “The export fails with GPU_DEVICE_LOST”Cause. The device was lost (a driver reset, another program, a sleep), or no longer runs the work it is given.
Fix. Retry in a new process or on a new device: the native host exits after answering, and the browser player makes the device again after a device loss. If the same frames lose the device again, render on the CPU (--renderer cpu) or lighten the heavy frames. decideRetry in alpha2/export-retry decides whether to retry.
EFFECT_ERROR on the CPU renderer
Section titled “EFFECT_ERROR on the CPU renderer”Cause. The project uses a runtime WGSL effect. The CPU renderer draws every built-in effect and transition, but WGSL needs a GPU.
Fix. Render that project with --renderer gpu (or renderer: "gpu"), on a machine with a GPU.
Browser setup
Section titled “Browser setup”No audio in the preview
Section titled “No audio in the preview”Cause. Audio preview moves the mixed audio to the audio thread through shared memory, which needs a cross-origin isolated page. Video preview, editing and export work without it.
Fix. Serve the page with both headers:
Cross-Origin-Opener-Policy: same-originCross-Origin-Embedder-Policy: require-corpcanShareAudioMemory() from alpha2/audio-timeline says whether the page is isolated. With require-corp, every cross-origin resource the page loads must allow it (CORS or Cross-Origin-Resource-Policy).
Console warning about the application/wasm MIME type
Section titled “Console warning about the application/wasm MIME type”`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower.Cause. The server sends .wasm files with another Content-Type.
Fix. Serve .wasm as application/wasm. It works either way; the fallback only compiles more slowly. If your bundler moves the files, pass their URL to init({ module_or_path }).
TypeScript errors from the dom-webcodecs types
Section titled “TypeScript errors from the dom-webcodecs types”Cause. mediabunny, the optional dependency behind alpha2/mediabunny, installs @types/dom-webcodecs 0.1.13, whose declarations clash with TypeScript 5.9’s DOM library.
Fix. Compile with skipLibCheck, or pin the newer types in your package.json:
"overrides": { "@types/dom-webcodecs": "0.1.19" }An app that imports alpha2/mediabunny also needs "ESNext.Disposable" in the lib of its tsconfig.json.
A browser export cannot encode H.264
Section titled “A browser export cannot encode H.264”Cause. Browser export encodes with the browser’s WebCodecs encoders, and not every browser encodes every codec at every size.
Fix. Ask first: canEncodeVideoTrack("avc", { width, height, rate }) returns null when the browser does not encode it. Try vp9 in WebM, or export natively. The editor’s bridge.videoEncoders() does the same check.
Text and fonts
Section titled “Text and fonts”Text draws in the wrong font
Section titled “Text draws in the wrong font”Cause. The engine never reads system fonts. It draws text with the font files it was given, matched by font_family. A family no given font has draws in the fallback order: the first font that has the glyphs.
Fix. Give the renderer the font file, in the same order everywhere: fonts on the worker host or addFontFile in the browser, --font on the CLI, fonts in Node.js and Python. A family matches the font’s own name table (typographic family, else family), ignoring ASCII case.
MISSING_INPUT: the project shows text, but no fonts were registered
Section titled “MISSING_INPUT: the project shows text, but no fonts were registered”Cause. The frame shows text or captions and no font was given at all.
Fix. Pass at least one font file, as above.
Text breaks onto different lines in the preview and the export
Section titled “Text breaks onto different lines in the preview and the export”Cause. The two renderers have different fonts, or the same fonts in a different order.
Fix. Use the same files in the same order. With the same font bytes, the browser’s WasmTextRasterizer and a native export draw the same text.
Exports
Section titled “Exports”A browser export stops on waiting tickets or missingSources
Section titled “A browser export stops on waiting tickets or missingSources”Cause. An export frame needs source frames the engine doesn’t have. beginExportFrame() returns a waiting ticket naming them (missingSources, missingFrames) instead of rendering.
Fix. Upload the frames it names and ask again: the export continues at the same frame. exportToSink calls your refill with them. A frame still waiting after four refills fails with RESOURCE_LIMIT at stage sources-not-held: the refill did not upload what was asked, or the uploads did not fit the frame budget. refill must use a DecoderRefillCoordinator made for the export, not the preview’s.
MISSING_INPUT or CONFORM_FAILED from a native export
Section titled “MISSING_INPUT or CONFORM_FAILED from a native export”Cause. A file the render needs was not given (MISSING_INPUT: an asset, an effect resource, a font or a frame), or a given file is offline or isn’t the media the project recorded (CONFORM_FAILED).
Fix. Give every source an --asset <source-id>=<path> (assets in Node.js and Python). alpha2-host conform reports, per source, what it found and what blocks, without rendering.
H.264 export fails with INVALID_INPUT on a server or on Windows N
Section titled “H.264 export fails with INVALID_INPUT on a server or on Windows N”Cause. The FFmpeg in the release archives is LGPL and has no software H.264 encoder. H.264 comes from the GPU’s encoder (Vulkan Video, NVENC, VideoToolbox, Media Foundation, D3D12) or from OpenH264. A CPU-only server, an arm64 server, an NVIDIA datacenter GPU, or Windows N/KN without the Media Feature Pack has none.
Fix.
- Install Cisco’s OpenH264:
npx @alpha2-sh/node install --openh264orpython -m alpha2 install --openh264. - Or export VP9 or AV1, which the runtime encodes on the CPU:
--video-codec vp9. capabilitiesreportsencode.h264.statuswith areasonand aremedybefore you export.
IO_ERROR: the output already exists
Section titled “IO_ERROR: the output already exists”Cause. An export never replaces a file unless asked.
Fix. Pass --overwrite (overwrite: true). It replaces the file only once the export is whole. OUTPUT_IN_USE means another running export is writing the same output.
RESOURCE_LIMIT, or the host exits without answering
Section titled “RESOURCE_LIMIT, or the host exits without answering”Cause. The export’s smallest working set doesn’t fit its memory budgets (RESOURCE_LIMIT), or the machine or container ran out of memory and the kernel ended the host (HOST_EXITED).
Fix. Run fewer exports at once (concurrency), lower the memory budgets, or give the container more memory.
Installing the native host
Section titled “Installing the native host”HOST_NOT_FOUND
Section titled “HOST_NOT_FOUND”Cause. The client looked for alpha2-host in the hostPath option, ALPHA2_HOST_PATH, the package, the cache and PATH, and found none.
Fix. Run npx @alpha2-sh/node install (or python -m alpha2 install), or point ALPHA2_HOST_PATH at an unpacked archive’s bin/alpha2-host.
HOST_LOAD_FAILED
Section titled “HOST_LOAD_FAILED”Cause. The system’s loader refused alpha2-host before it ran: a missing or mismatched FFmpeg, such as a thin archive on a system without FFmpeg 8.
Fix. Use a bundled archive, or install FFmpeg 8 for a thin one. No retry mends it.
The project is refused
Section titled “The project is refused”A document the engine refuses fails to load with a message that names the problem. The same check runs everywhere: validateProject(project) in alpha2/project returns the problems as strings before you load, and alpha2.validate_project does it in Python. Some messages:
| Message | Cause | Fix |
|---|---|---|
clips a and b overlap without a covering transition on track main |
One track shows one clip at a time. | Move one clip to another track, or add a transition over the overlap. |
clip inset references unknown source nope |
A source_id names no source. |
Fix the id, or add the source. |
missing field 'mode' |
An animatable value was written bare, such as "scale": { "x": 1, "y": 1 }. |
Wrap it: { "mode": "constant", "value": { "x": 1, "y": 1 } }. |
unsupported schema version 2 |
The document is for another engine version. | Use schema_version 1 with alpha2 0.4. |
has unknown field "float" |
A field the schema doesn’t have, often a typo. | Check the field against the schema reference. |
A project that loads can still have lint issues, which lintProject (alpha2.lint_project) reports without refusing: off_frame_boundary for a time between frames, unreached_keyframe for a keyframe no frame reaches (often one written in the wrong time base).
