remotion-dev/remotion · error · Error

${oldRelativePath} does not exist

Error message

${oldRelativePath} does not exist

What it means

During renameStaticFile, Browser Studio looks up the normalized old path in the project's canonical publicFiles map. If that key is absent, the source of the rename does not exist and the operation is rejected before any mutation is applied. The check uses the canonical (normalized) form, so the path must match exactly after normalization.

Source

Thrown at packages/browser-studio/src/browser-studio-project-controller.ts:532

		getFileSource: (fileName) =>
			Promise.resolve(getFileSource({fileName, project: getProject()})),
		redo,
		resetHistory: () => {
			undoStack.length = 0;
			redoStack.length = 0;
			emit(getUndoRedoEvent());
		},
		renameStaticFile: ({oldRelativePath, newRelativePath}) => {
			try {
				const oldPath = normalizePublicFilePath(oldRelativePath);
				const newPath = normalizePublicFilePath(newRelativePath);
				if (oldPath === newPath) {
					return Promise.resolve({success: true});
				}

				const publicFiles = getCanonicalPublicFiles(getProject());
				if (publicFiles[oldPath] === undefined) {
					throw new Error(`${oldRelativePath} does not exist`);
				}

				if (publicFiles[newPath] !== undefined) {
					throw new Error(`${newRelativePath} already exists`);
				}

				applyMutation({
					fileName: oldPath,
					nodePathMutationFiles: null,
					mutate: (project) => {
						const nextPublicFiles = getCanonicalPublicFiles(project);
						nextPublicFiles[newPath] = nextPublicFiles[oldPath];
						delete nextPublicFiles[oldPath];
						return {...project, publicFiles: nextPublicFiles};
					},
				});
				return Promise.resolve({success: true});
			} catch (error) {

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Refresh the current publicFiles list right before offering/performing the rename.
  2. Match the oldRelativePath to an existing key exactly (no leading slash, identical casing).
  3. Disable the rename action in the UI when the selected file no longer exists.
  4. Handle a 'not found' outcome gracefully instead of crashing the flow.

Example fix

// before
renameStaticFile({oldRelativePath: 'gone.png', newRelativePath: 'renamed.png'});

// after
const files = getCanonicalPublicFiles(project);
if (!files['gone.png']) {
	refreshFileList();
	return;
}
renameStaticFile({oldRelativePath: 'gone.png', newRelativePath: 'renamed.png'});
Defensive patterns

Strategy: validation

Validate before calling

// Before renameStaticFile
const canonical = getCanonicalPublicFiles(project);
const oldKey = normalizePublicFilePath(oldRelativePath);
if (canonical[oldKey] === undefined) {
  refreshPublicFiles(); // re-sync UI state
  return; // do not call rename
}

Type guard

const isExistingPublicFile = (project: VirtualProject, path: string): boolean =>
  Object.prototype.hasOwnProperty.call(getCanonicalPublicFiles(project), normalizePublicFilePath(path));

Try / catch

try {
  await ops.renameStaticFile({oldRelativePath, newRelativePath});
} catch (err) {
  if (String(err?.message ?? '').endsWith('does not exist')) {
    refreshPublicFiles(); // file list is stale
    return;
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling renameStaticFile with an oldRelativePath that is not a current key in project.publicFiles (after normalization). Happens when the file was already renamed, deleted, never existed, or when casing/leading-slash differs from the stored key.

Common situations: Stale UI state after another tab mutated the project; file already renamed/deleted in the same session; path-string mismatch (leading '/', case sensitivity on case-sensitive stores); race where the file is removed between read and rename.

Related errors


AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12). Data as JSON: /api/errors/25ea4dd411d81752. Report an issue: GitHub.