{"record":{"id":"5b95a794739a6064","repo":"gastownhall/beads","slug":"uow-rootuser-must-not-be-empty-5b95a7","errorCode":null,"errorMessage":"uow: rootUser must not be empty","messagePattern":"uow: rootUser must not be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/uow/external_doltserver_provider.go","lineNumber":39,"sourceCode":"\tdatabase string,\n\tserverLogFilePath string,\n\texternal configfile.ExternalDoltConfig,\n\trootUser string,\n\trootPassword string,\n\tproxyPort int,\n\tidleTimeout time.Duration,\n\tteamServer bool,\n\texpectedProjectID string,\n\topts ...ProviderOption,\n) (UnitOfWorkProvider, error) {\n\tif idleTimeout == 0 {\n\t\tidleTimeout = defaultProxyIdleTimeout\n\t}\n\tif database == \"\" {\n\t\treturn nil, fmt.Errorf(\"uow: database name must not be empty (caller should default to %q)\", \"beads\")\n\t}\n\tif rootUser == \"\" {\n\t\treturn nil, fmt.Errorf(\"uow: rootUser must not be empty\")\n\t}\n\tif err := external.Validate(); err != nil {\n\t\treturn nil, fmt.Errorf(\"uow: external: %w\", err)\n\t}\n\n\tabsServerRootDir, err := filepath.Abs(serverRootDir)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"uow: resolving server root dir: %w\", err)\n\t}\n\n\tif err := os.MkdirAll(absServerRootDir, config.BeadsDirPerm); err != nil {\n\t\treturn nil, fmt.Errorf(\"uow: creating server root directory: %w\", err)\n\t}\n\n\ttlsConfigName, err := registerExternalTLSConfig(external)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"uow: external TLS: %w\", err)\n\t}","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/uow/external_doltserver_provider.go#L21-L57","documentation":"The provider requires a non-empty rootUser, the Dolt superuser account used to administer/create the target database on the external Dolt SQL server. This guard exists because subsequent bootstrap steps (connecting as root, creating or healing the database) cannot proceed without it. It is a fail-fast validation before any network or filesystem work happens.","triggerScenarios":"Calling NewExternalDoltServerUOWProvider with rootUser == \"\" — e.g. config omitted the root user, an empty env var was passed through, or openProvider forwarded an unset field.","commonSituations":"External-server configuration (dolt server address/credentials) partially filled in; a deployment template left the root user blank; a migration from embedded mode to external server mode missed the new credential fields.","solutions":["Pass the Dolt root username explicitly via the rootUser parameter or the appropriate ProviderOption","Check the external-server config section for an empty root-user field and fill it in (typically \"root\")","Verify the env var or secret backing the root user actually resolves to a non-empty value in the runtime environment"],"exampleFix":"// before\nprovider, err := uow.NewExternalDoltServerUOWProvider(ctx, db, \"\", serverRoot, external)\n// after\nprovider, err := uow.NewExternalDoltServerUOWProvider(ctx, db, \"root\", serverRoot, external)","handlingStrategy":"validation","validationCode":"if rootUser == \"\" {\n    return fmt.Errorf(\"config: external dolt rootUser is required (usually \\\"root\\\")\")\n}","typeGuard":"func hasRootUser(user string) bool {\n    return strings.TrimSpace(user) != \"\"\n}","tryCatchPattern":"provider, err := uow.NewExternalDoltServerUOWProvider(ctx, db, root, dir, ext)\nif err != nil {\n    if strings.Contains(err.Error(), \"rootUser must not be empty\") {\n        return fmt.Errorf(\"misconfiguration: external-server rootUser missing: %w\", err)\n    }\n    return err\n}","preventionTips":["Populate rootUser from config/secret management at startup and fail fast if empty","Keep the external-server config fields (host, port, rootUser) validated together in one place","Use a config struct with required-field validation rather than scattered string args"],"tags":["config","validation","uow","dolt","auth"],"backgroundTag":"missing-required-config-value","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}