{"record":{"id":"86b3e84636769a55","repo":"remotion-dev/remotion","slug":"newrelativepath-already-exists","errorCode":null,"errorMessage":"${newRelativePath} already exists","messagePattern":"(.+?) already exists","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/browser-studio/src/browser-studio-project-controller.ts","lineNumber":536,"sourceCode":"\t\t\tundoStack.length = 0;\n\t\t\tredoStack.length = 0;\n\t\t\temit(getUndoRedoEvent());\n\t\t},\n\t\trenameStaticFile: ({oldRelativePath, newRelativePath}) => {\n\t\t\ttry {\n\t\t\t\tconst oldPath = normalizePublicFilePath(oldRelativePath);\n\t\t\t\tconst newPath = normalizePublicFilePath(newRelativePath);\n\t\t\t\tif (oldPath === newPath) {\n\t\t\t\t\treturn Promise.resolve({success: true});\n\t\t\t\t}\n\n\t\t\t\tconst publicFiles = getCanonicalPublicFiles(getProject());\n\t\t\t\tif (publicFiles[oldPath] === undefined) {\n\t\t\t\t\tthrow new Error(`${oldRelativePath} does not exist`);\n\t\t\t\t}\n\n\t\t\t\tif (publicFiles[newPath] !== undefined) {\n\t\t\t\t\tthrow new Error(`${newRelativePath} already exists`);\n\t\t\t\t}\n\n\t\t\t\tapplyMutation({\n\t\t\t\t\tfileName: oldPath,\n\t\t\t\t\tnodePathMutationFiles: null,\n\t\t\t\t\tmutate: (project) => {\n\t\t\t\t\t\tconst nextPublicFiles = getCanonicalPublicFiles(project);\n\t\t\t\t\t\tnextPublicFiles[newPath] = nextPublicFiles[oldPath];\n\t\t\t\t\t\tdelete nextPublicFiles[oldPath];\n\t\t\t\t\t\treturn {...project, publicFiles: nextPublicFiles};\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\treturn Promise.resolve({success: true});\n\t\t\t} catch (error) {\n\t\t\t\treturn Promise.reject(error);\n\t\t\t}\n\t\t},\n\t\tsubscribeToEvent: (listener) => {","sourceCodeStart":518,"sourceCodeEnd":554,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/browser-studio/src/browser-studio-project-controller.ts#L518-L554","documentation":"renameStaticFile refuses to overwrite an existing public file: if the normalized new path is already a key in canonical publicFiles, it throws before mutating. This is an intentional non-destructive guard so renames cannot silently clobber another asset.","triggerScenarios":"Calling renameStaticFile where newRelativePath (after normalization) equals an existing publicFiles key. Trivially reproduced by renaming 'a.png' to 'b.png' when 'b.png' already exists.","commonSituations":"User picks a name that is already taken; case-only rename on a case-insensitive store causing a collision; UI not checking target existence before submit; attempting to 'rename' onto an existing file to force overwrite.","solutions":["Pick a unique target name (append a suffix/number if needed).","Delete or move the existing target file first if overwrite is truly intended.","Check publicFiles for the target key before calling renameStaticFile and warn the user.","Offer an auto-renamed suggestion when a collision is detected."],"exampleFix":"// before\nrenameStaticFile({oldRelativePath: 'a.png', newRelativePath: 'b.png'}); // b.png exists\n\n// after\nconst files = getCanonicalPublicFiles(project);\nconst target = files['b.png'] ? 'b (1).png' : 'b.png';\nrenameStaticFile({oldRelativePath: 'a.png', newRelativePath: target});","handlingStrategy":"validation","validationCode":"// Before renameStaticFile\nconst canonical = getCanonicalPublicFiles(project);\nconst newKey = normalizePublicFilePath(newRelativePath);\nif (canonical[newKey] !== undefined) {\n  // suggest a unique name\n  newRelativePath = uniqueName(newKey, Object.keys(canonical));\n}\n// or block the action and inform the user","typeGuard":"const isUniquePublicFile = (project: VirtualProject, path: string): boolean =>\n  !Object.prototype.hasOwnProperty.call(getCanonicalPublicFiles(project), normalizePublicFilePath(path));","tryCatchPattern":"try {\n  await ops.renameStaticFile({oldRelativePath, newRelativePath});\n} catch (err) {\n  if (String(err?.message ?? '').endsWith('already exists')) {\n    showUser('That name is taken; choose another or delete the target first.');\n    return;\n  }\n  throw err;\n}","preventionTips":["Check the target key against current publicFiles before submitting the rename.","Offer auto-generated unique names when a collision is detected.","If overwrite is intended, require an explicit delete step first — never implicit overwrite.","Compare in normalized form to catch case/leading-slash collisions."],"tags":["public-files","browser-studio","rename","conflict","non-destructive"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}