{"record":{"id":"81828f95b30965c1","repo":"remotion-dev/remotion","slug":"no-root-file-found","errorCode":null,"errorMessage":"No Root file found","messagePattern":"No Root file found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/create-video/src/add-tailwind.ts","lineNumber":12,"sourceCode":"import fs from 'fs';\nimport path from 'path';\n\nexport const addTailwindRootCss = (projectRoot: string) => {\n\tconst rootFileTsx = path.join(projectRoot, 'src', 'Root.tsx');\n\tconst rootFileJsx = path.join(projectRoot, 'src', 'Root.jsx');\n\tconst indexCss = path.join(projectRoot, 'src', 'index.css');\n\n\tconst rootFile = fs.existsSync(rootFileTsx) ? rootFileTsx : rootFileJsx;\n\n\tif (!fs.existsSync(rootFile)) {\n\t\tthrow new Error('No Root file found');\n\t}\n\n\tconst root = fs.readFileSync(rootFile, 'utf-8');\n\n\tconst newFile = `import \"./index.css\";\\n${root}`;\n\tfs.writeFileSync(rootFile, newFile);\n\n\tconst css = `@import \"tailwindcss\";\\n`;\n\tfs.writeFileSync(indexCss, css);\n};\n\nexport const addTailwindToConfig = (projectRoot: string) => {\n\tconst configFileTs = path.join(projectRoot, 'remotion.config.ts');\n\tconst configFileJs = path.join(projectRoot, 'remotion.config.js');\n\n\tconst configFile = fs.existsSync(configFileTs) ? configFileTs : configFileJs;\n\n\tif (!fs.existsSync(configFile)) {","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/create-video/src/add-tailwind.ts#L1-L30","documentation":"Thrown by `addTailwindRootCss` (a create-video Tailwind setup step) when neither `src/Root.tsx` nor `src/Root.jsx` exists in the project root. The function needs to inject an `import './index.css'` line at the top of the Root file to wire up Tailwind. Without a Root file there is no entry point to modify.","triggerScenarios":"Running `create-video` with the Tailwind option on a template or existing project whose entry file is not named Root.tsx/Root.jsx or lives in a different directory. The step checks `src/Root.tsx` then `src/Root.jsx` and throws if both are absent.","commonSituations":"Using a custom template where the entry is `src/index.tsx` or `src/Composition.tsx`; running the Tailwind setup against a project that does not follow Remotion's default Root convention; a partially generated project missing the Root file.","solutions":["Ensure a `src/Root.tsx` (or `.jsx`) file exists before running the Tailwind setup; create it if needed and register your compositions there.","Use a template that ships with the conventional Root file.","If your entry is differently named, temporarily create `src/Root.tsx` that re-exports from your real entry, then run the setup."],"exampleFix":"// before: project has src/index.tsx but no src/Root.tsx\n// create src/Root.tsx:\n// after\nimport {registerRoot} from 'remotion';\nimport {RemotionRoot} from './Composition';\nregisterRoot(RemotionRoot);","handlingStrategy":"validation","validationCode":"import fs from 'fs';\nimport path from 'path';\n\nconst rootExists = (projectRoot: string): boolean =>\n  fs.existsSync(path.join(projectRoot, 'src', 'Root.tsx')) ||\n  fs.existsSync(path.join(projectRoot, 'src', 'Root.jsx'));","typeGuard":"const hasRootFile = (projectRoot: string): boolean =>\n  fs.existsSync(path.join(projectRoot, 'src', 'Root.tsx')) ||\n  fs.existsSync(path.join(projectRoot, 'src', 'Root.jsx'));","tryCatchPattern":null,"preventionTips":["Ensure your template ships src/Root.tsx before enabling Tailwind setup.","Follow the Remotion Root file convention (registerRoot in src/Root.tsx).","Run the Tailwind setup only against a fully generated project."],"tags":["create-video","tailwind","project-structure","setup"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}