{"record":{"id":"0f5146b63d70e75b","repo":"gastownhall/beads","slug":"server-externaldoltserver-dial-w","errorCode":null,"errorMessage":"server: ExternalDoltServer.Dial: %w","messagePattern":"server: ExternalDoltServer\\.Dial: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dbproxy/server/external_dolt_server.go","lineNumber":102,"sourceCode":"\nfunc (s *ExternalDoltServer) Stop(_ context.Context) error {\n\ts.started.Store(false)\n\treturn nil\n}\n\nfunc (s *ExternalDoltServer) Running(_ context.Context) bool {\n\treturn s.started.Load()\n}\n\nfunc (s *ExternalDoltServer) Dial(ctx context.Context) (net.Conn, error) {\n\tnetwork, addr := \"tcp\", net.JoinHostPort(s.host, strconv.Itoa(s.port))\n\tif s.socket != \"\" {\n\t\tnetwork, addr = \"unix\", s.socket\n\t}\n\tvar d net.Dialer\n\tconn, err := d.DialContext(ctx, network, addr)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"server: ExternalDoltServer.Dial: %w\", err)\n\t}\n\tif tc, ok := conn.(*net.TCPConn); ok {\n\t\t_ = tc.SetKeepAlive(true)\n\t\t_ = tc.SetKeepAlivePeriod(s.keepAlivePeriod)\n\t}\n\treturn conn, nil\n}\n","sourceCodeStart":84,"sourceCodeEnd":110,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dbproxy/server/external_dolt_server.go#L84-L110","documentation":"ExternalDoltServer.Dial dials a Dolt server the library did not start (an external dolt sql-server) over TCP or Unix socket, wrapping net.DialContext errors. Identical mechanics to DoltServer.Dial but for externally managed processes.","triggerScenarios":"Dialing an ExternalDoltServer whose host:port or socket was configured incorrectly, the external dolt sql-server is down or restarting, or ctx is cancelled before the dial completes.","commonSituations":"Stale configuration pointing at a server that was redeployed on another port; external server crashed or was OOM-killed; running in a different container/network namespace so localhost doesn't reach the server; socket file removed by tmpfs cleanup.","solutions":["Verify the external server is up: `dolt sql-server` status or ps/pgrep for the process","Check the configured address/socket against the server's actual --port/--socket flags","For unix sockets, confirm the client can read/write the socket file path (permissions, same mount namespace)","Add retry/backoff around Dial to tolerate brief restarts of the external server"],"exampleFix":"// before\nconn, err := extServer.Dial(ctx)\n// after\nvar conn net.Conn\nvar derr error\nfor i := 0; i < 5; i++ {\n    if conn, derr = extServer.Dial(ctx); derr == nil { break }\n    select { case <-ctx.Done(): return ctx.Err(); case <-time.After(time.Duration(i+1) * 500 * time.Millisecond): }\n}","handlingStrategy":"retry","validationCode":"// pre-flight the external server\nif sock != \"\" {\n    if _, err := os.Stat(sock); err != nil { return fmt.Errorf(\"external socket %s missing\", sock) }\n} else if c, err := net.DialTimeout(\"tcp\", hostPort, 2*time.Second); err != nil {\n    return fmt.Errorf(\"external dolt server %s unreachable: %w\", hostPort, err)\n} else { c.Close() }","typeGuard":null,"tryCatchPattern":"conn, err := extServer.Dial(ctx)\nif err != nil {\n    return fmt.Errorf(\"cannot reach external dolt server (is it running? right address?): %w\", err)\n}\ndefer conn.Close()","preventionTips":["Validate external server host/port/socket config at startup with a probe dial","Supervise the external dolt sql-server (systemd/k8s) and add Dial retries for restarts","Use an address reachable from the client's network namespace (avoid bare localhost across containers)"],"tags":["go","network","tcp","unix-socket","external-server"],"backgroundTag":"connection-refused","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}