{"record":{"id":"92bf2611c350ac84","repo":"juanfont/headscale","slug":"listing-original-clients-w","errorCode":null,"errorMessage":"listing original clients: %w","messagePattern":"listing original clients: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"integration/helpers.go","lineNumber":1154,"sourceCode":"// AddAndLoginClient adds a new tailscale client to a user and logs it in.\n// This combines the common pattern of:\n// 1. Creating a new node\n// 2. Finding the new node in the client list\n// 3. Getting the user to create a preauth key\n// 4. Logging in the new node.\nfunc (s *Scenario) AddAndLoginClient(\n\tt *testing.T,\n\tusername string,\n\tversion string,\n\theadscale ControlServer,\n\ttsOpts ...tsic.Option,\n) (TailscaleClient, error) {\n\tt.Helper()\n\n\t// Get the original client list\n\toriginalClients, err := s.ListTailscaleClients(username)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"listing original clients: %w\", err)\n\t}\n\n\t// Create the new node\n\terr = s.CreateTailscaleNodesInUser(username, version, 1, tsOpts...)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"creating tailscale node: %w\", err)\n\t}\n\n\t// Wait for the new node to appear in the client list\n\tvar newClient TailscaleClient\n\n\t_, err = backoff.Retry(t.Context(), func() (struct{}, error) {\n\t\tupdatedClients, err := s.ListTailscaleClients(username)\n\t\tif err != nil {\n\t\t\treturn struct{}{}, fmt.Errorf(\"listing updated clients: %w\", err)\n\t\t}\n\n\t\tif len(updatedClients) != len(originalClients)+1 {","sourceCodeStart":1136,"sourceCodeEnd":1172,"githubUrl":"https://github.com/juanfont/headscale/blob/565fd254d06c4c7f9a8cad1714a43445c79ba420/integration/helpers.go#L1136-L1172","documentation":"Returned by Scenario.AddAndLoginClient when s.ListTailscaleClients(username) fails while snapshotting the pre-existing client list. It wraps the underlying listing error; the add-and-login flow aborts before creating any node.","triggerScenarios":"Calling AddAndLoginClient when listing clients for the user fails — user's containers unreachable, Docker exec errors, or the headscale control connection used for listing is broken.","commonSituations":"Prior test steps left client containers stopped/unhealthy; Docker daemon flakiness under parallel suites; the username's network was torn down by an earlier cleanup.","solutions":["Check that the user's existing client containers are running before adding another","Inspect the wrapped listing error and container states (docker ps) for the failing client","Re-run the scenario if Docker was transiently unhealthy; prune leftover state first"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// ensure the user's clients are up before adding another\nclients, err := s.ListTailscaleClients(username)\nif err != nil {\n    return fmt.Errorf(\"precondition failed, cannot list clients: %w\", err)\n}\nfor _, c := range clients {\n    if !c.IsRunning() { // or equivalent status check\n        return fmt.Errorf(\"existing client unhealthy\")\n    }\n}","typeGuard":null,"tryCatchPattern":"c, err := s.AddAndLoginClient(t, user, ver, h, opts...)\nif err != nil {\n    if strings.Contains(err.Error(), \"listing original clients\") {\n        // inspect Docker health of that user's containers before retrying\n    }\n    return err\n}","preventionTips":["Verify container health between scenario phases","Clean scenario state between tests so listing starts from a known baseline"],"tags":["integration-test","scenario","docker","clients"],"backgroundTag":null,"analyzedSha":"565fd254d06c4c7f9a8cad1714a43445c79ba420","analyzedAt":"2026-08-15T13:12:30.133Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}