{"record":{"id":"e2efa54b44b519c9","repo":"gastownhall/beads","slug":"newexternalproxiedserveruowprovider-proxied-serve","errorCode":null,"errorMessage":"newExternalProxiedServerUOWProvider: proxied server root (from env or %s): %w","messagePattern":"newExternalProxiedServerUOWProvider: proxied server root \\(from env or (.+?)\\): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/uow_factory.go","lineNumber":436,"sourceCode":"\t\t// concurrent serve. `bd dolt stop` does not reap it in these modes.\n\t\tproxyIdle:    proxy.IdleTimeoutNever,\n\t\trootPassword: conn.ServerPassword,\n\t}, nil\n}\n\n// newExternalProxiedServerUOWProvider fronts a Dolt SQL server this process\n// neither started nor owns. \"Proxied\" in the name is the PROXY it builds, not\n// the workspace mode: since bd-emv a server-mode workspace lands here too, and\n// the paths it resolves (root, log) are the same ones proxied mode uses because\n// both modes root their server at the same directory.\nfunc newExternalProxiedServerUOWProvider(ctx context.Context, beadsDir string, topology sqlServerUOWTopology, opts ...uow.ProviderOption) (p uow.UnitOfWorkProvider, err error) {\n\tdefer func() { p, err = activateEventsJournalProvider(ctx, beadsDir, p, err) }()\n\trootPath, err := resolveProxiedServerRootPath(beadsDir)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"newExternalProxiedServerUOWProvider: resolve root path: %w\", err)\n\t}\n\tif err := validateProxiedServerRootPath(rootPath); err != nil {\n\t\treturn nil, fmt.Errorf(\"newExternalProxiedServerUOWProvider: proxied server root (from env or %s): %w\", configfile.ProxiedServerClientInfoFileName, err)\n\t}\n\n\tlogPath, isCustomLog, err := resolveProxiedServerLogPath(beadsDir)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"newExternalProxiedServerUOWProvider: resolve log path: %w\", err)\n\t}\n\tif isCustomLog {\n\t\tif err := validateProxiedServerLogPath(logPath); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"newExternalProxiedServerUOWProvider: proxied server log (from env or %s): %w\", configfile.ProxiedServerClientInfoFileName, err)\n\t\t}\n\t}\n\n\tif err := os.MkdirAll(rootPath, config.BeadsDirPerm); err != nil {\n\t\treturn nil, fmt.Errorf(\"newExternalProxiedServerUOWProvider: mkdir %s: %w\", rootPath, err)\n\t}\n\n\treturn uow.NewExternalDoltServerUOWProvider(\n\t\tctx,","sourceCodeStart":418,"sourceCodeEnd":454,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/uow_factory.go#L418-L454","documentation":"When bd builds an external proxied-server unit-of-work provider (cmd/bd/uow_factory.go newExternalProxiedServerUOWProvider), it resolves the server root directory via BEADS_PROXIED_SERVER_ROOT_PATH, the .beads/proxied_server_client_info.json sidecar, or the default Dolt dir, then validates it with validateProxiedServerRootPath. This error wraps any validation failure: the resolved root exists but is not a directory, or os.Stat failed with something other than NotExist (e.g. permission denied on a parent). The message names proxied_server_client_info.json because that sidecar is the usual source of the root path.","triggerScenarios":"BEADS_PROXIED_SERVER_ROOT_PATH or the sidecar root_path points at a regular file or symlink-to-file instead of a directory; the path exists but the process lacks search permission on a parent directory; a corrupt or hand-edited proxied_server_client_info.json contains a bogus root_path.","commonSituations":"A user set BEADS_PROXIED_SERVER_ROOT_PATH to a file path (or a stale path now occupied by a file); after switching between modes an old file sits where the root dir should be; restricted service accounts without execute permission on home directories.","solutions":["Check what exists at the resolved path: ls -la on the path from BEADS_PROXIED_SERVER_ROOT_PATH or the sidecar's root_path; if it is a file, remove or rename it so bd can use/create the directory","Fix or unset BEADS_PROXIED_SERVER_ROOT_PATH (unset it to fall back to the sidecar/default), or correct root_path in .beads/proxied_server_client_info.json (bd migrate-dolt-mode writes it)","Verify the parent directories are traversable by the current user (chmod/chown as needed)","Re-run bd migrate-dolt-mode to regenerate a clean proxied_server_client_info.json sidecar"],"exampleFix":"// before: env var points at a file\nexport BEADS_PROXIED_SERVER_ROOT_PATH=/home/me/beads-root.json\n// after: point at a (possibly not-yet-existing) directory\nexport BEADS_PROXIED_SERVER_ROOT_PATH=/var/lib/beads/shared-server/dolt","handlingStrategy":"validation","validationCode":"root := os.Getenv(\"BEADS_PROXIED_SERVER_ROOT_PATH\")\nif root != \"\" {\n\tif fi, err := os.Stat(root); err == nil && !fi.IsDir() {\n\t\treturn fmt.Errorf(\"BEADS_PROXIED_SERVER_ROOT_PATH %s is not a directory\", root)\n\t}\n}","typeGuard":"func isDirOrAbsent(path string) bool {\n\tfi, err := os.Stat(path)\n\treturn err != nil || fi.IsDir()\n}","tryCatchPattern":null,"preventionTips":["Only ever set BEADS_PROXIED_SERVER_ROOT_PATH to a directory path, never a file","Before switching server modes, run bd migrate-dolt-mode rather than hand-editing proxied_server_client_info.json","Verify parent-directory execute permissions for service accounts running bd","Keep the root on a writable, user-owned volume"],"tags":["go","proxied-server","path-validation"],"backgroundTag":"invalid-server-root-path","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}