{"record":{"id":"51b0977b3f25c325","repo":"Netflix/chaosmonkey","slug":"attributes-field-missing","errorCode":null,"errorMessage":"'attributes' field missing","messagePattern":"'attributes' field missing","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"spinnaker/fromjson.go","lineNumber":102,"sourceCode":"//\t \t  \"whitelist\": [\n//\t \t  \t{\n//\t \t  \t\"account\": \"test\",\n//\t \t  \t\"stack\": \"*\",\n//\t \t  \t\"region\": \"*\",\n//\t \t  \t\"detail\": \"*\"\n//\t \t  \t}\n//\t \t  ]\n//\t\t  }\nfunc fromJSON(js []byte) (*chaosmonkey.AppConfig, error) {\n\tparsed := new(parsedJSON)\n\terr := json.Unmarshal(js, parsed)\n\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"json unmarshal failed\")\n\t}\n\n\tif parsed.Attributes == nil {\n\t\treturn nil, errors.New(\"'attributes' field missing\")\n\t}\n\n\tif parsed.Attributes.ChaosMonkey == nil {\n\t\treturn nil, errors.New(\"'attributes.chaosMonkey' field missing\")\n\t}\n\n\tcm := parsed.Attributes.ChaosMonkey\n\n\tif cm.Enabled == nil {\n\t\treturn nil, errors.New(\"'attributes.chaosMonkey.enabled' field missing\")\n\t}\n\n\t// Check if mean time between kills is missing.\n\t// If not enabled, it's ok if it's missing\n\tif *cm.Enabled && cm.MeanTimeBetweenKillsInWorkDays == nil {\n\t\treturn nil, errors.New(\"attributes.chaosMonkey.meanTimeBetweenKillsInWorkDays missing\")\n\t}\n","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/Netflix/chaosmonkey/blob/eaa28fb761c0ebe8644d1333e5d164e9cc3071e9/spinnaker/fromjson.go#L84-L120","documentation":"fromJSON parses a Spinnaker pipeline/execution payload and requires a top-level 'attributes' object. If the JSON unmarshals but parsed.Attributes is nil, the payload has no attributes field, so a chaos-monkey AppConfig cannot be derived. The error is returned from fromJSON, which is invoked by spinnaker.Get.","triggerScenarios":"Calling spinnaker.Get (which calls fromJSON) on JSON whose root object lacks an 'attributes' key, e.g. an error response, an empty object {}, or a non-Spinnaker payload.","commonSituations":"Pointing chaos monkey at the wrong Spinnaker endpoint or path so it receives HTML/JSON error bodies; Spinnaker API version changes that reshape the response; misconfigured authentication causing an error payload to be returned instead of the real entity.","solutions":["Verify the Spinnaker endpoint URL and fetch path used by the Get call return the expected entity with an 'attributes' object","Log the raw response body when this error occurs to confirm what was actually returned","Check Spinnaker authentication (cert/key/user config) — a failed auth often yields a payload without attributes","Confirm the Spinnaker API version still nests chaos monkey config under attributes"],"exampleFix":"// before: fetching wrong URL\nbody := fetch(baseURL + \"/pipelines\")\n// after: fetch the entity endpoint that returns attributes\nbody := fetch(baseURL + \"/applications/myapp/serverGroups\")","handlingStrategy":"validation","validationCode":"var raw map[string]json.RawMessage\nif err := json.Unmarshal(body, &raw); err != nil { return err }\nif _, ok := raw[\"attributes\"]; !ok { return errors.New(\"payload has no attributes field\") }","typeGuard":"func hasAttributes(body []byte) bool {\n    var p struct{ Attributes map[string]any `json:\"attributes\"` }\n    return json.Unmarshal(body, &p) == nil && p.Attributes != nil\n}","tryCatchPattern":"cfg, err := sp.Get(app)\nif err != nil {\n    if strings.Contains(err.Error(), \"'attributes' field missing\") {\n        log.Printf(\"non-standard Spinnaker payload for %s: %v\", app, err)\n        return errUnexpectedPayload\n    }\n    return err\n}","preventionTips":["Log the raw response body when parsing fails to spot HTML/error payloads","Verify Spinnaker endpoint URLs and auth before deploying","Pin and test against the Spinnaker API version you depend on"],"tags":["go","json","spinnaker","missing-field"],"backgroundTag":"missing-required-argument","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"}