nektos/act · error

Job '%s' failed

Error message

Job '%s' failed

What it means

Aggregate failure signal: after all stages of the plan ran, handleFailure walks every run and, if any job's Result is 'failure', returns this error naming the first failing job. It is how act converts an in-job failure into a top-level non-zero exit for the whole invocation.

Source

Thrown at pkg/runner/runner.go:226

					})
				}
				pipeline = append(pipeline, common.NewParallelExecutor(maxParallel, stageExecutor...))
			}

			log.Debugf("PlanExecutor concurrency: %d", runner.config.GetConcurrentJobs())
			return common.NewParallelExecutor(runner.config.GetConcurrentJobs(), pipeline...)(ctx)
		})
	}

	return common.NewPipelineExecutor(stagePipeline...).Then(handleFailure(plan))
}

func handleFailure(plan *model.Plan) common.Executor {
	return func(_ context.Context) error {
		for _, stage := range plan.Stages {
			for _, run := range stage.Runs {
				if run.Job().Result == "failure" {
					return fmt.Errorf("Job '%s' failed", run.String())
				}
			}
		}
		return nil
	}
}

func selectMatrixes(originalMatrixes []map[string]interface{}, targetMatrixValues map[string]map[string]bool) []map[string]interface{} {
	matrixes := make([]map[string]interface{}, 0)
	for _, original := range originalMatrixes {
		flag := true
		for key, val := range original {
			if allowedVals, ok := targetMatrixValues[key]; ok {
				valToString := fmt.Sprintf("%v", val)
				if _, ok := allowedVals[valToString]; !ok {
					flag = false
				}
			}

View on GitHub (pinned to 4f41128141)

Solutions

  1. Scroll up in act's output to the actual failing step — this error only names the job, the root cause is logged above it.
  2. Re-run with `act -j <job>` to isolate the failing job, and `--verbose` for full logs.
  3. Fix the underlying step (test failure, missing tool, bad script) — this wrapper error itself needs no fix.
  4. For jobs that are allowed to fail, set `continue-on-error: true` or scope it with an `if:` condition.
Defensive patterns

Strategy: try-catch

Try / catch

err := runner.New(runner.NewConfig(...)).NewPlanExecutor(plan)(ctx)
if err != nil {
  if strings.Contains(err.Error(), "failed") {
    // inspect plan.Stages[*].Runs[*].Job().Result to find which job and why
  }
}

Prevention

When it happens

Trigger: Any job step exited non-zero (with continue-on-error not set), a service container or job container failed to start, or any runner-level error marked the job result as 'failure' during execution of the plan.

Common situations: Expected outcome of a failing test/build inside a run step; a script step exiting with the code of the last failed command; upstream errors [160]-[169] marking the job failed; using act to reproduce a red CI job locally.

Related errors


AI-assisted analysis of nektos/act@4f41128141 (2026-08-15). Data as JSON: /api/errors/5d21a497127a6246. Report an issue: GitHub.