# Troubleshooting

> Symptoms, causes and fixes for install errors, blank frames, missing audio, hanging scripts, vision artifacts and preview problems.

## Install

| Symptom | Cause | Fix |
| --- | --- | --- |
| `Cannot find module '.../skia.node'` | `skia-canvas` install script was blocked | approve it ([Getting started](/docs/getting-started/#2-write-packagejson-then-install)), then `npm rebuild skia-canvas` |
| Import fails immediately | Node < 22, or not an ES module project | upgrade Node; set `"type": "module"` |
| No adapter / GPU error | no WebGPU-capable GPU (VM, plain CI runner) | render on a machine with Metal or Vulkan; there is no CPU fallback |

## Picture

| Symptom | Cause | Fix |
| --- | --- | --- |
| Whole frame black | font not registered, or `NaN` from a signal | register every family before building text; keep signal outputs finite |
| Text missing or tofu | family name doesn't match a registered font | match `fontFamily` to the `family` you registered |
| Emoji missing | no emoji font | `FontManager.registerEmojiFont(...)` |
| Layer invisible | path wrong, opacity 0, off canvas, or LFS pointer | check `comp.lint()`; run `git lfs pull` |
| Text clipped | box narrower than the text | set `width` (or `width: "fill"`) |
| Animation stops early | keys past `durationFrames` | extend the layer (`animation_truncated`) |
| Layer jumps to the corner when animated | animated `y` from 0 instead of its layout value | animate to the placed value |
| Fades look murky grey | custom shader with straight alpha | output premultiplied alpha, blend with `srcFactor: "one"` |
| Metal/rough looks flat | no environment | add `Layer.environment()` or `Lighting.studio()` |
| Effect does nothing | strength on a 0–1 scale where it's 0–100 | check ranges in the [Effects reference](/docs/reference/effects/) |

## Sound

| Symptom | Cause | Fix |
| --- | --- | --- |
| Audio cuts out early | `Layer.audio` without `durationFrames` | set `durationFrames: totalFrames` |
| `audio_clipping` | mix too hot | lower volumes; `softLimit` SFX beds |
| `loudness_off_target` | mix level | adjust volume toward the `targetLufs` |

## Process

| Symptom | Cause | Fix |
| --- | --- | --- |
| Script never exits after rendering | native GPU/encoder threads | `process.exit()` at the end |
| Slow exports | too little parallelism or a shallow staging ring | raise `concurrency`; try `ringCapacity: 4` |

## Vision

| Symptom | Cause | Fix |
| --- | --- | --- |
| Cutout empty on a single still | vision reads the previous frame | render two consecutive frames with one renderer, keep the last |
| Ghosted double of the subject | frames rendered out of order (grid, jumps) | verify with the MP4 or consecutive frames |
| Wrong object cut out | subject choice | `classes: ["person"]` |
| Garment drops out | fast motion | `variant: "m"` or `keyBackground: true` |
| Halo on dark backgrounds | feathering | lower `featherRadius` or raise `maskThreshold` |
| Fails offline / in CI | models not cached | preload into `$FRAMEFIELDS_MODELS_DIR` or set `FRAMEFIELDS_MODELS_BASE_URL` |

## Preview

| Symptom | Cause | Fix |
| --- | --- | --- |
| Font or media 404 in the page | path built from `process.cwd()` | build paths from `import.meta.url`; pass `root` for folders outside the project |
| "No WebGPU" | browser without WebGPU | current Chrome, Edge or Safari |
| Preview stopped | last tab closed (5 s), or replaced | run it again; same URL |
| Cutouts look wrong while playing | device skipped frames | check paused, or in the export |

Still stuck? Open an issue at [github.com/gatewai-dev/framefields](https://github.com/gatewai-dev/framefields/issues) or ask on [Discord](https://discord.gg/cbqMGGme5).
