Skip to content

Conversation

@trulede
Copy link
Contributor

@trulede trulede commented Jun 8, 2025

Execution graph to detect cyclic tasks, replacing the TaskCalledTooManyTimesError mechanism.

Vertices in the graph are added for each unique call (to a task) and the PreventCycles feature of the graph is used to detect cyclic execution. The unique identifying properties are:

  • The task name, unique from the Taskfile AST/DAG mechanism.
  • The task hash, unique for an "instance" of a task call (e.g. set of vars).
  • Call "index" of the task, either from 'deps' or 'cmds'.
  • The sources method value, propagated as a call "token". This addresses a special case where a task call is cyclic, but the sources change between each cycle, and thus the task call should continue.

Although this method has worked remarkably well, it could be beneficial to have a mechanism to disable the detection: Environment variable (of course) and perhaps attached to an existing CLI parameter (--force).

fixes #820
fixes #2302

@trulede
Copy link
Contributor Author

trulede commented Jun 8, 2025

@korverdev Would you like to try this for you use case mentioned in comments of #820?

Clone the PR and then run task like this:
go run ./cmd/task -d <your directory> <your task>

@jberkenbilt
Copy link
Contributor

I can confirm that this PR also fixes #2302

@pd93 pd93 self-requested a review July 3, 2025 22:45
CodeTaskInternal
CodeTaskNameConflict
CodeTaskCalledTooManyTimes
CodeTaskCalledTooManyTimes // Depreciated: replaced by CodeTaskCyclicExecutionDetected.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spelling:

Suggested change
CodeTaskCalledTooManyTimes // Depreciated: replaced by CodeTaskCyclicExecutionDetected.
CodeTaskCalledTooManyTimes // Deprecated: replaced by CodeTaskCyclicExecutionDetected.

func (err *TaskCyclicExecutionDetectedError) Error() string {
if len(err.CallingTaskName) > 0 {
return fmt.Sprintf(
`task: Cyclic task call execution detected for task %q (calling task %q)`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd simplify the wording a little: task: Call cycle detected for task %q (calling task %q)

)
} else {
return fmt.Sprintf(
`task: Cyclic task call execution detected for task %q`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto: task: Call cycle detected for task %q.

CodeTaskCancelled
CodeTaskMissingRequiredVars
CodeTaskNotAllowedVars
CodeTaskCyclicExecutionDetected
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might CodeTaskCallCycleDetected be a better name?

Comment on lines +96 to +98
// TaskCyclicExecutionDetectedError is returned when the Execution Graph detects
// a cyclic execution condition.
type TaskCyclicExecutionDetectedError struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: I'd use CallCycle instead of CyclicExecution everywhere:

Suggested change
// TaskCyclicExecutionDetectedError is returned when the Execution Graph detects
// a cyclic execution condition.
type TaskCyclicExecutionDetectedError struct {
// TaskCallCycleDetectedError is returned when the Execution Graph detects
// a call cycle.
type TaskCallCycleDetectedError struct {

@mjpieters
Copy link
Contributor

This PR also fixes #2546

@korverdev
Copy link

korverdev commented Jan 19, 2026

@trulede Sorry about the late follow up. Last year got really crazy for me.

I'm afraid I can't test this on my example. We had to pull the trigger on replacing task with another tool due to this limitation.

Is there anything I can do to get this over the line?

@andreynering
Copy link
Member

@trulede Mind rebasing this PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

undetected dependency loop or deadlock with run: when_changed "probably an cyclic dep or infinite loop" on huge graphs

5 participants