{"record":{"id":"0f286bd68523120e","repo":"Netflix/chaosmonkey","slug":"unexpected-status-code-d-error-s","errorCode":null,"errorMessage":"unexpected status code: %d. error: %s","messagePattern":"unexpected status code: (.+?)\\. error: (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"spinnaker/terminator.go","lineNumber":195,"sourceCode":"\t\t}\n\t*/\n\n\tvar fields struct {\n\t\tHealth []map[string]interface{} `json:\"health\"`\n\t\tError  string                   `json:\"error\"`\n\t}\n\n\terr = json.Unmarshal(body, &fields)\n\tif err != nil {\n\t\treturn \"\", errors.Wrap(err, fmt.Sprintf(\"json unmarshal failed, body: %s\", body))\n\t}\n\n\tif resp.StatusCode != http.StatusOK {\n\t\tif fields.Error == \"\" {\n\t\t\treturn \"\", fmt.Errorf(\"unexpected status code: %d. body: %s\", resp.StatusCode, body)\n\t\t}\n\n\t\treturn \"\", fmt.Errorf(\"unexpected status code: %d. error: %s\", resp.StatusCode, fields.Error)\n\t}\n\n\t// In some cases, an instance may be missing health information.\n\t// We just return a blank otherID in that case\n\tif len(fields.Health) < 2 {\n\t\treturn \"\", nil\n\t}\n\n\totherID, ok := fields.Health[1][\"instanceId\"].(string)\n\tif !ok {\n\t\treturn \"\", nil\n\t}\n\n\t// If the instance id is the same, there is no alternate\n\tif ins.ID() == otherID {\n\t\treturn \"\", nil\n\t}\n","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/Netflix/chaosmonkey/blob/eaa28fb761c0ebe8644d1333e5d164e9cc3071e9/spinnaker/terminator.go#L177-L213","documentation":"Variant of the non-200 handling in OtherID(): when Spinnaker responds with a non-200 status and the decoded body includes a populated Error field, that server-side error string is surfaced instead of the raw body.","triggerScenarios":"Calling OtherID when Spinnaker returns 4xx/5xx AND the JSON body's error field is non-empty, e.g. instance not found or backend cloud-provider error relayed by Spinnaker.","commonSituations":"Invalid instance ID, instance deleted concurrently, Spinnaker forwarding a cloud API failure.","solutions":["Read the embedded Spinnaker error string to identify the server-side cause","Validate the instance ID and cloud account before terminating","Treat instance-not-found as idempotent success where safe","Check Spinnaker/cloud provider health for backend errors"],"exampleFix":"// before\nreturn \"\", fmt.Errorf(\"unexpected status code: %d. error: %s\", resp.StatusCode, fields.Error)\n// after\nif resp.StatusCode == http.StatusNotFound {\n    log.Printf(\"instance already gone: %s\", fields.Error)\n    return \"\", nil\n}\nreturn \"\", fmt.Errorf(\"unexpected status code: %d. error: %s\", resp.StatusCode, fields.Error)","handlingStrategy":"try-catch","validationCode":"// confirm the target instance ID exists in Spinnaker before executing","typeGuard":null,"tryCatchPattern":"if err != nil {\n    // error embeds Spinnaker's server-side error string\n    log.Printf(\"spinnaker rejected request: %v\", err)\n    if strings.Contains(err.Error(), \"not found\") {\n        return nil // idempotent\n    }\n    return err\n}","preventionTips":["Parse the embedded error field, don't just retry blindly","Validate instance/account before calling","Handle concurrent terminations gracefully","Monitor Spinnaker backend health"],"tags":["http","spinnaker","instance-lookup"],"backgroundTag":"unexpected-http-status","analyzedSha":"eaa28fb761c0ebe8644d1333e5d164e9cc3071e9","analyzedAt":"2026-09-03T17:04:39.020Z","contentChangedAt":"2026-09-03T17:04:39.020Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}