{"record":{"id":"045311bd7e50a620","repo":"owasp-amass/amass","slug":"listsessions-status-s","errorCode":null,"errorMessage":"listSessions: status=%s","messagePattern":"listSessions: status=(.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/api/client/v1/client.go","lineNumber":126,"sourceCode":"\tvar out CreateSessionResponse\n\tif err := json.Unmarshal([]byte(resp.Body), &out); err != nil {\n\t\treturn uuid.UUID{}, err\n\t}\n\n\treturn uuid.Parse(out.SessionToken)\n}\n\n// Lists the active session and associated tokens on the server.\nfunc (c *Client) ListSessions(ctx context.Context) ([]uuid.UUID, error) {\n\tresp, err := amasshttp.RequestWebPage(ctx, c.httpClient, &amasshttp.Request{URL: c.base + \"/sessions/list\"})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif resp.StatusCode != http.StatusOK {\n\t\tmsg, err := readJSONError(resp.Body)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"listSessions: status=%s\", resp.Status)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"listSessions: status=%s error=%s\", resp.Status, msg)\n\t}\n\n\tvar out ListSessionsResponse\n\tif err := json.Unmarshal([]byte(resp.Body), &out); err != nil {\n\t\treturn nil, err\n\t}\n\n\ttokens := make([]uuid.UUID, 0, len(out.SessionTokens))\n\tfor _, t := range out.SessionTokens {\n\t\ttoken, err := uuid.Parse(t)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ttokens = append(tokens, token)\n\t}\n\treturn tokens, nil","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/owasp-amass/amass/blob/79299dce87b0085db0f2f4ef3e9c52cccb49f514/engine/api/client/v1/client.go#L108-L144","documentation":"This error is returned by Client.ListSessions when the GET to {base}/api/v1/sessions/list returns a status other than 200 OK and the response body could not be parsed as a JSON error envelope (readJSONError failed). Only the HTTP status string is available because the server replied with a non-JSON body (HTML error page, empty body, plain text). The caller receives no session tokens.","triggerScenarios":"Calling Client.ListSessions when the server responds non-200 with a non-JSON body: proxy/gateway HTML 502/503/504 pages, 404 HTML page because the path or API version is wrong, empty 500 from a crashed handler, or plain-text 401 from an auth middleware.","commonSituations":"Wrong base URL or port in NewClient so a proxy or wrong service answers; client/server API version mismatch (no /api/v1/sessions/list route); server down or restarting behind a load balancer; network middleware (ingress controller) intercepting the request.","solutions":["Run Client.HealthCheck first to verify you are reaching the correct amass API server before interpreting the failure.","Verify the NewClient URL and that the server exposes /api/v1/sessions/list for the version you compiled against (404 implies path/version mismatch).","If the status is 5xx, check proxy and server logs (nginx, ALB, amass server) for the underlying outage and retry once the service is healthy.","Confirm no auth middleware is intercepting with a plain-text 401/403; supply required credentials or headers.","Upgrade client and server together if the API surface changed."],"exampleFix":"// before: ignoring failure mode\nsessions, err := c.ListSessions(ctx)\n\n// after: health-check and distinguish retryable statuses\nif !c.HealthCheck(ctx) {\n    return fmt.Errorf(\"amass API unreachable; not calling ListSessions\")\n}\nsessions, err := c.ListSessions(ctx)\nif err != nil && strings.Contains(err.Error(), \"50\") {\n    sessions, err = c.ListSessions(ctx) // retry once on 5xx\n}","handlingStrategy":"try-catch","validationCode":"// Gate ListSessions behind a health/auth probe\nif !client.HealthCheck(ctx) {\n    return fmt.Errorf(\"amass API unreachable; skipping ListSessions\")\n}\nresp, err := http.Get(baseURL + \"/api/v1/sessions/list\")\nif err == nil && resp.StatusCode == http.StatusNotFound {\n    return fmt.Errorf(\"server does not expose /api/v1/sessions/list; version mismatch?\")\n}","typeGuard":null,"tryCatchPattern":"sessions, err := client.ListSessions(ctx)\nif err != nil {\n    if strings.Contains(err.Error(), \"listSessions: status=\") &&\n        !strings.Contains(err.Error(), \"error=\") {\n        // non-JSON body: gateway/HTML page — check infra, retry with backoff\n        return retryWithBackoff(func() error {\n            sessions, err = client.ListSessions(ctx)\n            return err\n        })\n    }\n    return err\n}","preventionTips":["HealthCheck before listing so you fail fast with a clear message instead of a bare status string.","Keep client and server versions aligned; a 404 here usually means the route moved or the server is the wrong version.","Configure proxies to pass JSON error bodies through instead of HTML error pages.","Apply bounded retry with backoff only for 5xx statuses; 4xx statuses need configuration fixes, not retries.","Remember this variant lacks the server's error detail — correlate with server/gateway logs at the same timestamp."],"tags":["http","api","session","go"],"backgroundTag":"http-error-response","analyzedSha":"79299dce87b0085db0f2f4ef3e9c52cccb49f514","analyzedAt":"2026-09-06T08:22:48.198Z","contentChangedAt":"2026-09-06T08:22:48.198Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}