nektos/act · error

Unable to Close file: %v

Error message

Unable to Close file: %v

What it means

Thrown by act's expression interpreter when actionlint's expression parser fails to parse the text inside ${{ }}. The message embeds actionlint's own parse error, which names the offending token and column. This is a syntax-level failure in the GitHub Actions expression language.

Source

Thrown at pkg/exprparser/functions.go:237

	if len(files) == 0 {
		return "", nil
	}

	hasher := sha256.New()

	for _, file := range files {
		f, err := os.Open(file)
		if err != nil {
			return "", fmt.Errorf("Unable to os.Open: %v", err)
		}

		if _, err := io.Copy(hasher, f); err != nil {
			return "", fmt.Errorf("Unable to io.Copy: %v", err)
		}

		if err := f.Close(); err != nil {
			return "", fmt.Errorf("Unable to Close file: %v", err)
		}
	}

	return hex.EncodeToString(hasher.Sum(nil)), nil
}

func (impl *interperterImpl) getNeedsTransitive(job *model.Job) []string {
	needs := job.Needs()

	for _, need := range needs {
		parentNeeds := impl.getNeedsTransitive(impl.config.Run.Workflow.GetJob(need))
		needs = append(needs, parentNeeds...)
	}

	return needs
}

func (impl *interperterImpl) always() (bool, error) {

View on GitHub (pinned to 4f41128141)

Solutions

  1. Read the embedded parser message — it points to the exact token and column.
  2. Simplify the expression or move logic into the run: script.
  3. Lint the workflow with actionlint to catch it statically.
  4. Compare against GitHub's expression syntax docs; no shell constructs allowed inside ${{ }}.

Example fix

# before
${{ env.GREETING && echo hi }}
# after
${{ env.GREETING != '' && 'hi' || 'bye' }}
Defensive patterns

Strategy: validation

Validate before calling

func expressionParses(expr string) bool {
  _, err := actionlint.NewExprParser().Parse(actionlint.NewExprLexer(expr))
  return err == nil
}

Try / catch

if v, err := interp.Evaluate(raw, status); err != nil {
  if strings.Contains(err.Error(), 'Failed to parse') {
    // surface the actionlint message to the workflow author
    return fmt.Errorf('bad expression %q: %w', raw, err)
  }
  return err
}

Prevention

When it happens

Trigger: Typos like ${{ env. }} or ${{ if(x) }}; unbalanced parentheses/quotes; using shell syntax inside expressions ($(), backticks); missing '}}' terminator (act appends it, so inner stray '}}' breaks too).

Common situations: Converting shell logic into expressions; complex nested ternaries; copy-pasting from docs with smart quotes; older act versions being stricter/looser than GitHub.

Related errors


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