nektos/act · error

invalid format delimiter '%v' not found before end of file

Error message

invalid format delimiter '%v' not found before end of file

What it means

Thrown by the .env file parser (parse_env_file.go) when a line uses the multi-line heredoc syntax KEY<<DELIMITER but the terminating DELIMITER line is never found before EOF. act scans subsequent lines for an exact match to the delimiter; reaching end of file without it is an error.

Source

Thrown at pkg/container/parse_env_file.go:59

			if singleLineEnv != -1 && (multiLineEnv == -1 || singleLineEnv < multiLineEnv) {
				localEnv[line[:singleLineEnv]] = line[singleLineEnv+1:]
			} else if multiLineEnv != -1 {
				multiLineEnvContent := ""
				multiLineEnvDelimiter := line[multiLineEnv+2:]
				delimiterFound := false
				for s.Scan() {
					content := s.Text()
					if content == multiLineEnvDelimiter {
						delimiterFound = true
						break
					}
					if multiLineEnvContent != "" {
						multiLineEnvContent += "\n"
					}
					multiLineEnvContent += content
				}
				if !delimiterFound {
					return fmt.Errorf("invalid format delimiter '%v' not found before end of file", multiLineEnvDelimiter)
				}
				localEnv[line[:multiLineEnv]] = multiLineEnvContent
			} else {
				return fmt.Errorf("invalid format '%v', expected a line with '=' or '<<'", line)
			}
		}
		env = &localEnv
		return s.Err()
	}
}

View on GitHub (pinned to 4f41128141)

Solutions

  1. Add the exact delimiter line (no indentation, no trailing spaces) that matches the text after <<.
  2. Ensure the file uses LF line endings; CRLF makes 'DELIMITER\r' != 'DELIMITER'.
  3. Quote the value as a single-line fallback if multiline is not required.
  4. Validate the env file locally before passing it to act.

Example fix

# before (.env)
SSH_KEY<<EOF
-----BEGIN KEY-----
# after (.env)
SSH_KEY<<EOF
-----BEGIN KEY-----
-----END KEY-----
EOF
Defensive patterns

Strategy: validation

Validate before calling

func validateEnvHeredocs(path string) error {
  f, _ := os.Open(path)
  defer f.Close()
  s := bufio.NewScanner(f)
  var open string
  for s.Scan() {
    line := s.Text()
    if open != '' {
      if line == open { open = '' }
      continue
    }
    if i := strings.Index(line, '<<'); i >= 0 {
      open = strings.TrimSpace(line[i+2:])
    }
  }
  if open != '' { return fmt.Errorf('unterminated delimiter %q', open) }
  return nil
}

Try / catch

if err := parseEnvFile(e, path, &env)(); err != nil {
  if strings.Contains(err.Error(), 'delimiter') { /* fix env file heredoc */ } else { return err }
}

Prevention

When it happens

Trigger: An env file passed via --env-file or the GITHUB_ENV/update logic contains 'EOF<<MSG' style entries where the closing marker line is missing, misspelled, indented, or has trailing whitespace.

Common situations: Hand-written .env files using act's heredoc extension for multiline secrets/keys; shell heredoc habits (indentable terminators) carried into .env files; CRLF line endings making the delimiter line not exactly equal.

Related errors


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