nektos/act · error

`uses` key references invalid workflow path '%s'. Must start

Error message

`uses` key references invalid workflow path '%s'. Must start with './' if it's a local workflow, or must start with '<org>/<repo>/' and include an '@' if it's a remote workflow

What it means

Job type detection rejects a `uses:` value that looks like a YAML path but is neither a local reusable workflow (must start with ./) nor a valid remote one (must match org/repo/path.yaml@ref). The regexes require at least two path segments after the org/repo prefix and a literal `@version` suffix.

Source

Thrown at pkg/model/workflow.go:548

func (j *Job) Type() (JobType, error) {
	isReusable := j.Uses != ""

	if isReusable {
		isYaml, _ := regexp.MatchString(`\.(ya?ml)(?:$|@)`, j.Uses)

		if isYaml {
			isLocalPath := strings.HasPrefix(j.Uses, "./")
			isRemotePath, _ := regexp.MatchString(`^[^.](.+?/){2,}.+\.ya?ml@`, j.Uses)
			hasVersion, _ := regexp.MatchString(`\.ya?ml@`, j.Uses)

			if isLocalPath {
				return JobTypeReusableWorkflowLocal, nil
			} else if isRemotePath && hasVersion {
				return JobTypeReusableWorkflowRemote, nil
			}
		}

		return JobTypeInvalid, fmt.Errorf("`uses` key references invalid workflow path '%s'. Must start with './' if it's a local workflow, or must start with '<org>/<repo>/' and include an '@' if it's a remote workflow", j.Uses)
	}

	return JobTypeDefault, nil
}

// ContainerSpec is the specification of the container to use for the job
type ContainerSpec struct {
	Image       string            `yaml:"image"`
	Env         map[string]string `yaml:"env"`
	Ports       []string          `yaml:"ports"`
	Volumes     []string          `yaml:"volumes"`
	Options     string            `yaml:"options"`
	Credentials map[string]string `yaml:"credentials"`
	Entrypoint  string
	Args        string
	Name        string
	Reuse       bool
}

View on GitHub (pinned to 4f41128141)

Solutions

  1. Local reusable workflow: `uses: ./.github/workflows/name.yml` — keep the ./ prefix.
  2. Remote reusable workflow: `uses: OWNER/REPO/.github/workflows/name.yml@v1` — include the full path and @ref.
  3. Verify the referenced file exists at that path in the target repo/ref.
  4. If the job is not meant to be reusable-workflow syntax, move the reference to a step-level `uses:` instead.

Example fix

# before
jobs:
  deploy:
    uses: myorg/myrepo/.github/workflows/deploy.yml
# after
jobs:
  deploy:
    uses: myorg/myrepo/.github/workflows/deploy.yml@v1
Defensive patterns

Strategy: type-guard

Validate before calling

var remoteRe = regexp.MustCompile(`^[^.][^/]+/[^/]+/.+\.ya?ml@.+$`)
func validReusableUses(uses string) bool {
    return strings.HasPrefix(uses, "./") || remoteRe.MatchString(uses)
}

Type guard

func classifyUses(uses string) (local bool, remote bool) {
    if strings.HasPrefix(uses, "./") {
        return true, false
    }
    if remoteRe.MatchString(uses) { // org/repo/path.yml@ref
        return false, true
    }
    return false, false
}

Prevention

When it happens

Trigger: A job declares `uses: ./.github/workflows/deploy.yml` without @ref, `uses: org/repo/path.yml` missing @ref, `uses: org/repo` with .yml ext confusion, or `uses: ./other.yml` where detection ran because isYaml matched but the prefix rules failed.

Common situations: Forgetting the `@ref` (required even for local-style remote refs on GitHub); missing `./` prefix for local workflows; wrong number of path segments; assuming local workflows do not need a ref.

Related errors


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