How to Fix Missing Assets During Remotion Render (staticFile vs Relative Paths)
A render that fails to find a file that clearly exists on disk is almost always a path resolution mismatch between preview and the actual render bundle.
Remotion Studio's preview runs your composition in a browser connected to a local dev server, where a path like ../assets/video.mp4 or ./logo.png resolves against that server's file structure. Rendering is a completely different process: your composition gets bundled into a standalone artifact, and that same relative path frequently doesn't point to anything inside the bundle.
The fix: staticFile()
Anything referenced with staticFile(), sourced from your project's public/ folder, is guaranteed to resolve the same way in both preview and render, because Remotion handles bundling that folder consistently:
import { staticFile, Img, Video } from "remotion";
<Img src={staticFile("logo.png")} />
<Video src={staticFile("clips/intro.mp4")} />The path passed to staticFile() is always relative to your public/ folder, regardless of where in your component tree the call happens — that consistency is the entire point.
Remote assets (URLs)
A full URL (https://...) works directly without staticFile, since it's not a local path at all — Remotion fetches it the same way in preview and render. The failure mode there is different: network access, CORS, or the remote host being unavailable at render time, not a path resolution issue.
Quick way to confirm this is your issue
If the error names a file that you can confirm exists in your project, and the path is anything other than a staticFile() call or a full URL, that mismatch is almost certainly the cause — swap it to staticFile() and re-render.
This is exactly the class of mistake a template only makes once, gets caught, and never makes again — because the structural code stops changing after it's built.
See the templates