{"record":{"id":"c20de0ec36adf6ab","repo":"gastownhall/beads","slug":"uow-external-w","errorCode":null,"errorMessage":"uow: external: %w","messagePattern":"uow: external: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/uow/external_doltserver_provider.go","lineNumber":42,"sourceCode":"\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}\n\n\tep, err := proxy.GetCreateDatabaseProxyServerEndpoint(absServerRootDir, proxy.OpenOpts{\n\t\tBackend:     proxy.BackendExternal,","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/uow/external_doltserver_provider.go#L24-L60","documentation":"This is a wrapped error: the external Dolt server connection descriptor (host, port, credentials, etc.) failed its own Validate() check and the provider re-wraps it as \"uow: external: <reason>\". The provider defers detailed validation to the ExternalDoltServer type and surfaces its message so callers get a single consolidated error. The real cause is always in the wrapped message after the prefix.","triggerScenarios":"Calling NewExternalDoltServerUOWProvider with an ExternalDoltServer config that fails Validate() — e.g. empty host, invalid/missing port, missing password for the app user, or malformed address.","commonSituations":"Hand-edited config pointing at the external Dolt server (typo in host, port 0, empty password); secrets not injected in a container/CI environment so credential fields are empty; struct built programmatically with fields partially set.","solutions":["Read the wrapped cause after \"uow: external: \" to see which field Validate() rejected","Fix the offending field in the ExternalDoltServer config (host, port, user, password)","Run the ExternalDoltServer's Validate() yourself before calling the provider to get the error earlier and un-wrapped"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if err := external.Validate(); err != nil {\n    return fmt.Errorf(\"invalid external dolt server config: %w\", err)\n}\n// only then call NewExternalDoltServerUOWProvider","typeGuard":null,"tryCatchPattern":"provider, err := uow.NewExternalDoltServerUOWProvider(ctx, db, root, dir, ext)\nif err != nil {\n    var cause error\n    if errors.Unwrap(err) != nil && strings.HasPrefix(err.Error(), \"uow: external: \") {\n        errors.As(err, &cause) // inspect wrapped Validate() failure\n        return fmt.Errorf(\"external dolt server config invalid: %w\", cause)\n    }\n    return err\n}","preventionTips":["Call external.Validate() yourself before provider construction to get an unwrapped error","Validate host, port, and credentials together when loading external-server config","Keep secrets injection verified at startup so credential fields are never empty at call time"],"tags":["config","validation","uow","dolt","wrapped-error"],"backgroundTag":"schema-validation-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}