{"record":{"id":"9372560fad13762e","repo":"janhq/jan","slug":"settings-general-couldnotrelocatetoroot","errorCode":"settings:general.couldNotRelocateToRoot","errorMessage":"settings:general.couldNotRelocateToRoot","messagePattern":"settings:general\\.couldNotRelocateToRoot","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"web-app/src/routes/settings/general.tsx","lineNumber":167,"sourceCode":"    })\n\n    if (selectedPath === janDataFolder) return\n    if (selectedPath !== null) {\n      setSelectedNewPath(selectedPath as string)\n      setIsDialogOpen(true)\n    }\n  }\n\n  const confirmDataFolderChange = async () => {\n    if (selectedNewPath) {\n      try {\n        await serviceHub.models().stopAllModels()\n        serviceHub.events().emit(SystemEvent.KILL_SIDECAR)\n        setTimeout(async () => {\n          try {\n            // Prevent relocating to root directory (e.g., C:\\ or D:\\ on Windows, / on Unix)\n            if (isRootDir(selectedNewPath))\n              throw new Error(t('settings:general.couldNotRelocateToRoot'))\n            await serviceHub.app().relocateJanDataFolder(selectedNewPath)\n            setJanDataFolder(selectedNewPath)\n            // Only relaunch if relocation was successful\n            window.core?.api?.relaunch()\n            setSelectedNewPath(null)\n            setIsDialogOpen(false)\n          } catch (error) {\n            console.error(error)\n            toast.error(\n              error instanceof Error\n                ? error.message\n                : t('settings:general.failedToRelocateDataFolder')\n            )\n          }\n        }, 1000)\n      } catch (error) {\n        console.error('Failed to relocate data folder:', error)\n        // Revert the data folder path on error","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/janhq/jan/blob/fad3f12a147d138388a66f0d92a02b2675f65294/web-app/src/routes/settings/general.tsx#L149-L185","documentation":"Thrown in confirmDataFolderChange (general.tsx:167) when the user-selected path for the Jan data folder is a filesystem root (isRootDir returns true). The guard prevents relocating app data into C:\\, D:\\, or /, which would scatter thousands of files across the root and break relative paths. Message is i18n key 'settings:general.couldNotRelocateToRoot'.","triggerScenarios":"User opens the data-folder picker and selects a drive root (Windows C:\\ or D:\\, Unix /). isRootDir(selectedNewPath) returns true and the throw fires before relocateJanDataFolder runs.","commonSituations":"User wants the data on a different drive and picks the drive letter root instead of a named subfolder; accidental root selection in the native directory picker; user misunderstanding that any folder is acceptable but the root is not.","solutions":["Select a named subfolder on the target drive, e.g. D:\\JanData instead of D:\\.","The UI shows this as a toast; pick a non-root path and confirm again.","If migrating to a new drive, create the target folder first in your file manager, then select it."],"exampleFix":"// before\nif (isRootDir(selectedNewPath))\n  throw new Error(t('settings:general.couldNotRelocateToRoot'))\n// after: validate before showing the confirm dialog, disable the Confirm button\nconst isRoot = isRootDir(selectedNewPath)\n// <Button disabled={isRoot}>{t('settings:general.confirm')}</Button>\n{isRoot && <p className=\"text-warning\">{t('settings:general.couldNotRelocateToRoot')}</p>}","handlingStrategy":"validation","validationCode":"function isSafeDataFolder(p: string): boolean {\n  return p.trim().length > 0 && !isRootDir(p)\n}\n// before confirmDataFolderChange runs:\nif (!isSafeDataFolder(selectedNewPath)) {\n  // disable Confirm button, show inline warning\n  return\n}","typeGuard":"function isNonRootPath(p: unknown): p is string {\n  return typeof p === 'string' && p.trim().length > 0 && !isRootDir(p)\n}","tryCatchPattern":"try {\n  await serviceHub.app().relocateJanDataFolder(selectedNewPath)\n} catch (e) {\n  // the root-dir guard throws before this; other relocation errors land here\n  toast.error(e instanceof Error ? e.message : t('settings:general.failedToRelocateDataFolder'))\n}","preventionTips":["Validate the picked path before showing the confirm dialog.","Disable the Confirm button when isRootDir is true so the user never hits the throw.","Suggest a named subfolder when the user picks a drive root.","Run isRootDir on every platform's picker result, not just Windows."],"tags":["settings","data-folder","filesystem","guard","i18n","react","typescript"],"backgroundTag":null,"analyzedSha":"fad3f12a147d138388a66f0d92a02b2675f65294","analyzedAt":"2026-08-12T20:33:47.516Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}