{"record":{"id":"a2a4b04709347125","repo":"owasp-amass/amass","slug":"createsession-status-s-error-s","errorCode":null,"errorMessage":"createSession: status=%s error=%s","messagePattern":"createSession: status=(.+?) error=(.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/api/client/v1/client.go","lineNumber":105,"sourceCode":"\t\treturn uuid.UUID{}, err\n\t}\n\n\tresp, err := amasshttp.RequestWebPage(ctx, c.httpClient, &amasshttp.Request{\n\t\tMethod: http.MethodPost,\n\t\tBody:   string(raw),\n\t\tURL:    c.base + \"/sessions\",\n\t\tHeader: amasshttp.Header{\"Content-Type\": []string{\"application/json\"}},\n\t})\n\tif err != nil {\n\t\treturn uuid.UUID{}, err\n\t}\n\n\tif resp.StatusCode != http.StatusCreated {\n\t\tmsg, err := readJSONError(resp.Body)\n\t\tif err != nil {\n\t\t\treturn uuid.UUID{}, fmt.Errorf(\"createSession: status=%s\", resp.Status)\n\t\t}\n\t\treturn uuid.UUID{}, fmt.Errorf(\"createSession: status=%s error=%s\", resp.Status, msg)\n\t}\n\n\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 {","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/owasp-amass/amass/blob/79299dce87b0085db0f2f4ef3e9c52cccb49f514/engine/api/client/v1/client.go#L87-L123","documentation":"This error is returned by Client.CreateSession when the POST to {base}/api/v1/sessions returns a non-201 status and readJSONError successfully extracted the server's error message from the JSON body. It carries the HTTP status plus the server-provided error detail, making it the informative variant of the createSession failure. The embedded message is what the server chose to report (e.g. invalid configuration, duplicate session, unauthorized).","triggerScenarios":"Calling Client.CreateSession when the server rejects the session creation and returns a structured JSON error: invalid or unsupported Config fields in the POST body, authentication/authorization failure (401/403), request validation failure (400), or server-side failure (500) that the API reports as a JSON error envelope.","commonSituations":"Submitting a Config the server version does not accept (schema drift between client and server); expired or missing credentials on an authenticated deployment; malformed or nil-adjacent config values failing server-side validation; server storage/DB errors surfaced as 500 with a JSON message.","solutions":["Read the error=%s portion of the message — it contains the server's own explanation — and address that specific cause first.","Log the full request payload (the marshaled config) and compare against the API contract for the server version you are running.","Check authentication: if status is 401/403, supply or refresh credentials expected by the server deployment.","Update the client library and server to matching versions if the config schema changed between releases.","Retry after fixing server-side issues if the status is 5xx and the message indicates a transient backend failure."],"exampleFix":"// before: ignoring the server-provided detail\nif err != nil {\n    return err\n}\n\n// after: branch on the status and surface the server message\nif err != nil {\n    var httpErr *clientv1.StatusError\n    if errors.As(err, &httpErr) && strings.HasPrefix(httpErr.Status, \"5\") {\n        return retryable(fmt.Errorf(\"createSession: %w\", err))\n    }\n    return fmt.Errorf(\"session rejected by server: %w\", err)\n}","handlingStrategy":"try-catch","validationCode":"// Validate the config before sending it to the server\nraw, err := json.Marshal(cfg)\nif err != nil { return err }\nif len(raw) == 0 || !json.Valid(raw) {\n    return fmt.Errorf(\"config does not serialize to valid JSON\")\n}\n// Ensure server health/auth before submitting\nif !client.HealthCheck(ctx) {\n    return fmt.Errorf(\"amass API server unhealthy; fix server/auth before CreateSession\")\n}","typeGuard":null,"tryCatchPattern":"tok, err := client.CreateSession(ctx, cfg)\nif err != nil {\n    msg := err.Error()\n    if i := strings.Index(msg, \"error=\"); i >= 0 {\n        serverMsg := msg[i+len(\"error=\"):]\n        log.Printf(\"server rejected session creation: %s\", serverMsg)\n        // branch on serverMsg to fix config/auth accordingly\n    }\n    if strings.Contains(msg, \"401\") || strings.Contains(msg, \"403\") {\n        return refreshCredentialsAndRetry()\n    }\n    return err\n}","preventionTips":["Parse the error= suffix — it is the server's own diagnosis; build handling around it.","Keep client config structs in sync with the server version's schema to avoid 400 validation failures.","Handle 401/403 by refreshing or supplying credentials before retrying.","Log the serialized request config on failure to reproduce against the API contract.","Treat 5xx statuses with a JSON message as transient and apply bounded retries."],"tags":["http","api","session","server-error","go"],"backgroundTag":"api-error-response","analyzedSha":"79299dce87b0085db0f2f4ef3e9c52cccb49f514","analyzedAt":"2026-09-06T08:22:48.198Z","contentChangedAt":"2026-09-06T08:22:48.198Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}