{"record":{"id":"aba9bf90012bb9d0","repo":"Netflix/chaosmonkey","slug":"missing-region-field-in-exception","errorCode":null,"errorMessage":"missing region field in exception","messagePattern":"missing region field in exception","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"spinnaker/fromjson.go","lineNumber":164,"sourceCode":"\tvar meanTime int\n\tvar minTime int\n\n\tif cm.MeanTimeBetweenKillsInWorkDays != nil {\n\t\tmeanTime = *cm.MeanTimeBetweenKillsInWorkDays\n\t}\n\n\tif cm.MinTimeBetweenKillsInWorkDays != nil {\n\t\tminTime = *cm.MinTimeBetweenKillsInWorkDays\n\t}\n\n\t// Exceptions must have a non-blank region field\n\tfor _, exception := range cm.Exceptions {\n\t\tif exception.Account == \"\" {\n\t\t\treturn nil, errors.New(\"missing account field in exception\")\n\t\t}\n\n\t\tif exception.Region == \"\" {\n\t\t\treturn nil, errors.New(\"missing region field in exception\")\n\t\t}\n\t}\n\n\tcfg := chaosmonkey.AppConfig{\n\t\tEnabled:                        *cm.Enabled,\n\t\tRegionsAreIndependent:          cm.RegionsAreIndependent,\n\t\tGrouping:                       grouping,\n\t\tMeanTimeBetweenKillsInWorkDays: meanTime,\n\t\tMinTimeBetweenKillsInWorkDays:  minTime,\n\t\tExceptions:                     cm.Exceptions,\n\t\tWhitelist:                      cm.Whitelist,\n\t}\n\n\treturn &cfg, nil\n}\n\n// parsedJson is the parsed JSON representation\ntype parsedJSON struct {","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/Netflix/chaosmonkey/blob/eaa28fb761c0ebe8644d1333e5d164e9cc3071e9/spinnaker/fromjson.go#L146-L182","documentation":"Every entry in attributes.chaosMonkey.exceptions must also specify a region. fromJSON returns this error when an exception has a non-empty account but an empty Region, because the comment in source states exceptions must have a non-blank region field.","triggerScenarios":"Calling spinnaker.Get on a payload whose exceptions array contains an object like {\"account\":\"prod-account\"} with no region key (or region: \"\").","commonSituations":"Hand-editing exceptions and omitting region; assuming account-only exceptions (e.g. account-wide exemptions) are allowed — the current schema requires region; migration scripts copying partial exception records.","solutions":["Add the region (e.g. \"us-east-1\") to every exception object in attributes.chaosMonkey.exceptions","If the intent is to exempt the whole account, create one exception entry per region in that account","Strip out malformed exception entries before saving the config"],"exampleFix":"// before\n\"exceptions\": [{\"account\": \"prod-account\"}]\n// after\n\"exceptions\": [{\"account\": \"prod-account\", \"region\": \"us-east-1\"}]","handlingStrategy":"validation","validationCode":"var cm struct {\n    Exceptions []struct {\n        Account string `json:\"account\"`\n        Region  string `json:\"region\"`\n    } `json:\"exceptions\"`\n}\njson.Unmarshal(cmRaw, &cm)\nfor i, e := range cm.Exceptions {\n    if e.Region == \"\" { return fmt.Errorf(\"exception %d missing region\", i) }\n}","typeGuard":"func exceptionsHaveRegions(cmRaw []byte) bool {\n    var p struct {\n        Exceptions []struct{ Region string `json:\"region\"` } `json:\"exceptions\"`\n    }\n    if json.Unmarshal(cmRaw, &p) != nil { return false }\n    for _, e := range p.Exceptions { if e.Region == \"\" { return false } }\n    return true\n}","tryCatchPattern":"cfg, err := sp.Get(app)\nif err != nil {\n    if strings.Contains(err.Error(), \"missing region field in exception\") {\n        return fmt.Errorf(\"app %s exception entries lack region: %w\", app, err)\n    }\n    return err\n}","preventionTips":["Validate account+region pairs together on every exception entry","For account-wide exemptions, generate one entry per region programmatically","Reject empty-string regions in config-writing tooling"],"tags":["go","json","spinnaker","missing-field","exceptions"],"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"}