{"record":{"id":"99a3205822ef9eb0","repo":"henrygd/beszel","slug":"client-not-initialized","errorCode":null,"errorMessage":"client not initialized","messagePattern":"client not initialized","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/hub/systems/system.go","lineNumber":767,"sourceCode":"\t}\n\tconn, err := dialer.Dial(network, addr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tsshConn, chans, reqs, err := ssh.NewClientConn(conn, addr, config)\n\tif err != nil {\n\t\t_ = conn.Close()\n\t\treturn nil, err\n\t}\n\treturn ssh.NewClient(sshConn, chans, reqs), nil\n}\n\n// createSessionWithTimeout creates a new SSH session with a timeout to avoid hanging\n// in case of network issues\nfunc (sys *System) createSessionWithTimeout(timeout time.Duration) (*ssh.Session, error) {\n\tclient := sys.client.Load()\n\tif client == nil {\n\t\treturn nil, fmt.Errorf(\"client not initialized\")\n\t}\n\n\tctx, cancel := context.WithTimeout(sys.ctx, timeout)\n\tdefer cancel()\n\n\tsessionChan := make(chan *ssh.Session, 1)\n\terrChan := make(chan error, 1)\n\n\tgo func() {\n\t\tif session, err := client.NewSession(); err != nil {\n\t\t\terrChan <- err\n\t\t} else {\n\t\t\tsessionChan <- session\n\t\t}\n\t}()\n\n\tselect {\n\tcase session := <-sessionChan:","sourceCodeStart":749,"sourceCodeEnd":785,"githubUrl":"https://github.com/henrygd/beszel/blob/b38fb7dafa60812cc22e6a84ce313e94f1ce0a32/internal/hub/systems/system.go#L749-L785","documentation":"createSessionWithTimeout in internal/hub/systems/system.go:767 loads the system's cached SSH client via sys.client.Load(); if the atomic pointer is nil it means the SSH connection has never been established or was already closed, so no session can be created. This is a lifecycle guard preventing a nil-pointer dereference on golang.org/x/crypto/ssh Client methods.","triggerScenarios":"createSessionWithTimeout (called via runSSHOperation and an anonymous wrapper) runs while sys.client holds nil — e.g. the system was paused/stopped and closeSSHConnection or connectToSSH disconnect set the client to nil, or the system is being initialized concurrently and an SSH operation races ahead of the first connect.","commonSituations":"Hub restarting/initializing systems from the database while monitoring timers fire before the SSH connection completes; an agent host that dropped its connection so the manager cleared the client; calling SSH-based operations (logs, container info) on a paused system.","solutions":["Ensure the system's SSH connection is established (connectToSSH / Initialize) before issuing SSH operations","Check the system is not paused/stopped in the hub UI before triggering SSH actions","Reconnect the system and retry once the client is initialized","If the race persists, add a readiness guard/wait around runSSHOperation calls"],"exampleFix":"// before\nif sys.IsPaused() == false {\n    data, err := sys.GetData(ctx) // may hit 'client not initialized'\n}\n// after\nif sys.IsConnected() {\n    data, err := sys.GetData(ctx)\n} else {\n    if err := sys.Connect(); err != nil { return err }\n    data, err := sys.GetData(ctx)\n}","handlingStrategy":"try-catch","validationCode":"if sys.GetClient() == nil { // atomic client pointer\n    return errors.New(\"system SSH client not initialized; connect first\")\n}","typeGuard":"func (sys *System) HasClient() bool {\n    return sys.client.Load() != nil\n}","tryCatchPattern":"session, err := sys.createSessionWithTimeout(timeout)\nif err != nil {\n    if err.Error() == \"client not initialized\" {\n        if cerr := sys.Connect(); cerr != nil { return cerr }\n        session, err = sys.createSessionWithTimeout(timeout)\n    }\n    if err != nil { return err }\n}","preventionTips":["Always connect the system (Initialize/connectToSSH) before issuing SSH operations","Gate SSH operations on an IsConnected/HasClient check","Treat paused/stopped systems as ineligible for SSH commands","Watch for races between initialization and the first monitoring tick"],"tags":["ssh","lifecycle","race-condition"],"backgroundTag":"ssh-client-not-initialized","analyzedSha":"b38fb7dafa60812cc22e6a84ce313e94f1ce0a32","analyzedAt":"2026-08-31T15:10:10.149Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}