{"record":{"id":"d9e0969307f182bb","repo":"Netflix/chaosmonkey","slug":"invalid-attributes-chaosmonkey-meantimebetweenkill","errorCode":null,"errorMessage":"invalid attributes.chaosMonkey.meanTimeBetweenKillsInWorkDays: %d","messagePattern":"invalid attributes\\.chaosMonkey\\.meanTimeBetweenKillsInWorkDays: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"spinnaker/fromjson.go","lineNumber":126,"sourceCode":"\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\n\tif *cm.Enabled && cm.MinTimeBetweenKillsInWorkDays == nil {\n\t\treturn nil, errors.New(\"attributes.chaosMonkey.minTimeBetweenKillsInWorkDays missing\")\n\t}\n\n\tif *cm.Enabled && (*cm.MeanTimeBetweenKillsInWorkDays <= 0) {\n\t\treturn nil, fmt.Errorf(\"invalid attributes.chaosMonkey.meanTimeBetweenKillsInWorkDays: %d\", cm.MeanTimeBetweenKillsInWorkDays)\n\t}\n\n\tgrouping := chaosmonkey.Cluster\n\n\tswitch cm.Grouping {\n\tcase \"app\":\n\t\tgrouping = chaosmonkey.App\n\tcase \"stack\":\n\t\tgrouping = chaosmonkey.Stack\n\tcase \"cluster\":\n\t\tgrouping = chaosmonkey.Cluster\n\tdefault:\n\t\t// If not enabled, the user may not have specified a grouping at all,\n\t\t// in which case we stick with the default\n\t\tif *cm.Enabled {\n\t\t\treturn nil, errors.Errorf(\"Unknown grouping: %s\", cm.Grouping)\n\t\t}\n\t}","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/Netflix/chaosmonkey/blob/eaa28fb761c0ebe8644d1333e5d164e9cc3071e9/spinnaker/fromjson.go#L108-L144","documentation":"After presence checks, fromJSON validates that meanTimeBetweenKillsInWorkDays is strictly positive when chaos monkey is enabled. A zero or negative value fails this check and produces this fmt.Errorf with the value interpolated.","triggerScenarios":"Calling spinnaker.Get where chaosMonkey.enabled is true and meanTimeBetweenKillsInWorkDays <= 0 (e.g. 0 or a negative number).","commonSituations":"A UI or script defaulting the field to 0; manual config where the interval was never set; unit conversion bugs writing days as 0.","solutions":["Set meanTimeBetweenKillsInWorkDays to a positive integer (e.g. 5) in attributes.chaosMonkey","Add upstream validation that rejects intervals <= 0 before persisting the config","Note the message contains a pre-existing bug: it formats the pointer cm.MeanTimeBetweenKillsInWorkDays, not *cm.MeanTimeBetweenKillsInWorkDays, so the printed value is a pointer — check the raw config for the actual number"],"exampleFix":"// before\n\"chaosMonkey\": {\"enabled\": true, \"meanTimeBetweenKillsInWorkDays\": 0}\n// after\n\"chaosMonkey\": {\"enabled\": true, \"meanTimeBetweenKillsInWorkDays\": 5}","handlingStrategy":"validation","validationCode":"var cm struct {\n    Enabled *bool `json:\"enabled\"`\n    Mean    *int  `json:\"meanTimeBetweenKillsInWorkDays\"`\n}\njson.Unmarshal(cmRaw, &cm)\nif cm.Enabled != nil && *cm.Enabled && (cm.Mean == nil || *cm.Mean <= 0) {\n    return errors.New(\"meanTimeBetweenKillsInWorkDays must be a positive integer\")\n}","typeGuard":"func meanIntervalIsValid(cmRaw []byte) bool {\n    var p struct {\n        Enabled *bool `json:\"enabled\"`\n        Mean    *int  `json:\"meanTimeBetweenKillsInWorkDays\"`\n    }\n    if json.Unmarshal(cmRaw, &p) != nil || p.Enabled == nil || !*p.Enabled { return true }\n    return p.Mean != nil && *p.Mean > 0\n}","tryCatchPattern":"cfg, err := sp.Get(app)\nif err != nil {\n    if strings.Contains(err.Error(), \"invalid attributes.chaosMonkey.meanTimeBetweenKillsInWorkDays\") {\n        return fmt.Errorf(\"app %s has non-positive kill interval: %w\", app, err)\n    }\n    return err\n}","preventionTips":["Reject intervals <= 0 in any UI or script that writes chaosMonkey config","Clamp or default the value server-side when it is unset rather than writing 0","Remember the error message prints a pointer due to a bug — read the raw config to see the real value"],"tags":["go","json","spinnaker","invalid-value","config-validation"],"backgroundTag":"invalid-config-value","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"}