{"record":{"id":"ade951c137552b8a","repo":"Netflix/chaosmonkey","slug":"could-not-retrieve-list-of-apps-v","errorCode":null,"errorMessage":"could not retrieve list of apps: %v","messagePattern":"could not retrieve list of apps: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"schedule/schedule.go","lineNumber":45,"sourceCode":"\t\"github.com/Netflix/chaosmonkey/v2\"\n\t\"github.com/Netflix/chaosmonkey/v2/config\"\n\t\"github.com/Netflix/chaosmonkey/v2/deploy\"\n\t\"github.com/Netflix/chaosmonkey/v2/grp\"\n)\n\n// Populate populates the termination schedule with the random\n// terminations for a list of apps. If the specified list of apps is empty,\n// then it will\nfunc (s *Schedule) Populate(d deploy.Deployment, getter chaosmonkey.AppConfigGetter, chaosConfig *config.Monkey, apps []string) error {\n\tc := make(chan *deploy.App)\n\n\t// If the caller explicitly a set of apps, use those\n\t// If they did not, do all apps\n\tif len(apps) == 0 {\n\t\tvar err error\n\t\tapps, err = d.AppNames()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"could not retrieve list of apps: %v\", err)\n\t\t}\n\t}\n\n\tgo d.Apps(c, apps)\n\ti := 0 // number of apps already processed\n\tfor app := range c {\n\t\tif i >= chaosConfig.MaxApps() {\n\t\t\tbreak\n\t\t}\n\n\t\ti++\n\n\t\tcfg, err := getter.Get(app.Name())\n\n\t\tif err != nil {\n\t\t\tlog.Printf(\"WARNING: Could not retrieve config for app=%s. %s\", app.Name(), err)\n\t\t\tcontinue\n\t\t}","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/Netflix/chaosmonkey/blob/eaa28fb761c0ebe8644d1333e5d164e9cc3071e9/schedule/schedule.go#L27-L63","documentation":"Populate() needs the list of app names when the caller did not pass any explicitly. It calls d.AppNames(); if that lookup fails the error is wrapped with this message and Populate aborts, so no chaos monkey schedule entries are populated.","triggerScenarios":"Calling Populate with an empty apps slice while the underlying AppNames() call (typically backed by Spinnaker or a configured app source) returns an error such as auth failure or unreachable API.","commonSituations":"Spinnaker endpoint misconfigured, expired credentials, network outage, or the app-list API returning 5xx during scheduling.","solutions":["Inspect the wrapped %v inner error to find the root cause (auth, DNS, HTTP status)","Verify Spinnaker endpoint/credentials configuration used by AppNames","Check network connectivity to the app source API","Retry; transient upstream failures resolve on the next scheduler run"],"exampleFix":"// before\napps, err = d.AppNames()\nif err != nil {\n    return fmt.Errorf(\"could not retrieve list of apps: %v\", err)\n}\n// after\napps, err = d.AppNames()\nif err != nil {\n    log.Printf(\"AppNames failed: %v; falling back to explicit list\", err)\n    return fmt.Errorf(\"could not retrieve list of apps: %w\", err) // preserve chain\n}","handlingStrategy":"try-catch","validationCode":"if len(apps) == 0 {\n    // ensure the app source (Spinnaker) endpoint and credentials are configured\n    if cfg.SpinnakerEndpoint() == \"\" {\n        return fmt.Errorf(\"no apps provided and spinnaker endpoint not configured\")\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := sched.Populate(ctx, nil); err != nil {\n    var appErr interface{ Unwrap() error }\n    if errors.As(err, &appErr) { log.Printf(\"root cause: %v\", errors.Unwrap(err)) }\n    // fall back to a cached app list or retry later\n}","preventionTips":["Validate Spinnaker configuration at startup","Provide an explicit apps list to avoid the AppNames lookup when possible","Monitor app-source API health","Retry transient failures with backoff"],"tags":["scheduler","app-discovery","error-wrapping"],"backgroundTag":"app-list-fetch-failed","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"}