{"record":{"id":"8159e4a70e291cfc","repo":"kubernetes/kops","slug":"unable-to-execute-tasks-circular-dependency-s","errorCode":null,"errorMessage":"Unable to execute tasks (circular dependency): %s","messagePattern":"Unable to execute tasks \\(circular dependency\\): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/executor.go","lineNumber":188,"sourceCode":"\t\t\t}\n\t\t\tif tryAgainLaterCount == n {\n\t\t\t\tklog.Infof(\"Continuing to run %s\", formatTaskCount(tryAgainLaterCount))\n\t\t\t} else {\n\t\t\t\tklog.Infof(\"No progress made, sleeping before retrying %s\", formatTaskCount(n))\n\t\t\t}\n\t\t\ttime.Sleep(e.options.WaitAfterAllTasksFailed)\n\t\t}\n\t}\n\n\t// Raise error if not all tasks done - this means they depended on each other\n\tvar notDone []string\n\tfor _, ts := range taskStates {\n\t\tif !ts.done {\n\t\t\tnotDone = append(notDone, ts.key)\n\t\t}\n\t}\n\tif len(notDone) != 0 {\n\t\treturn fmt.Errorf(\"Unable to execute tasks (circular dependency): %s\", strings.Join(notDone, \", \"))\n\t}\n\n\treturn nil\n}\n\nfunc (e *executor[T]) forkJoin(ctx context.Context, tasks []*taskState[T]) []error {\n\tif len(tasks) == 0 {\n\t\treturn nil\n\t}\n\n\tresults := make([]error, len(tasks))\n\tvar resultsMutex sync.Mutex\n\n\tvar wg sync.WaitGroup\n\tfor i := 0; i < len(tasks); i++ {\n\t\twg.Add(1)\n\t\tgo func(ts *taskState[T], index int) {\n\t\t\tdefer wg.Done()","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/executor.go#L170-L206","documentation":"Thrown by RunTasks after the executor stopped making progress: some tasks never finished because they (transitively) depend on each other, forming a cycle. The message lists the task keys still not done. This is a task-graph construction bug — typically two tasks each declaring the other as a dependency, or self-dependencies introduced by fi.FindDependencies on shared resources.","triggerScenarios":"Thrown at upup/pkg/fi/executor.go:188 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Inspect the listed task keys and trace their dependency declarations to find the cycle","Avoid mutual dependencies: dependency edges should follow resource producer→consumer order","Check fi.FindDependencies usage — tasks referencing each other's outputs can create cycles","Reproduce locally with a dry-run to dump the task graph"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}