{"record":{"id":"e0406c562c9e56dc","repo":"nektos/act","slug":"invalid-format-delimiter-v-not-found-before-end","errorCode":null,"errorMessage":"invalid format delimiter '%v' not found before end of file","messagePattern":"invalid format delimiter '(.+?)' not found before end of file","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/container/parse_env_file.go","lineNumber":59,"sourceCode":"\t\t\tif singleLineEnv != -1 && (multiLineEnv == -1 || singleLineEnv < multiLineEnv) {\n\t\t\t\tlocalEnv[line[:singleLineEnv]] = line[singleLineEnv+1:]\n\t\t\t} else if multiLineEnv != -1 {\n\t\t\t\tmultiLineEnvContent := \"\"\n\t\t\t\tmultiLineEnvDelimiter := line[multiLineEnv+2:]\n\t\t\t\tdelimiterFound := false\n\t\t\t\tfor s.Scan() {\n\t\t\t\t\tcontent := s.Text()\n\t\t\t\t\tif content == multiLineEnvDelimiter {\n\t\t\t\t\t\tdelimiterFound = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tif multiLineEnvContent != \"\" {\n\t\t\t\t\t\tmultiLineEnvContent += \"\\n\"\n\t\t\t\t\t}\n\t\t\t\t\tmultiLineEnvContent += content\n\t\t\t\t}\n\t\t\t\tif !delimiterFound {\n\t\t\t\t\treturn fmt.Errorf(\"invalid format delimiter '%v' not found before end of file\", multiLineEnvDelimiter)\n\t\t\t\t}\n\t\t\t\tlocalEnv[line[:multiLineEnv]] = multiLineEnvContent\n\t\t\t} else {\n\t\t\t\treturn fmt.Errorf(\"invalid format '%v', expected a line with '=' or '<<'\", line)\n\t\t\t}\n\t\t}\n\t\tenv = &localEnv\n\t\treturn s.Err()\n\t}\n}\n","sourceCodeStart":41,"sourceCodeEnd":70,"githubUrl":"https://github.com/nektos/act/blob/4f411281417e88660bea1c1a1749aa71ae0bd60f/pkg/container/parse_env_file.go#L41-L70","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Add the exact delimiter line (no indentation, no trailing spaces) that matches the text after <<.","Ensure the file uses LF line endings; CRLF makes 'DELIMITER\\r' != 'DELIMITER'.","Quote the value as a single-line fallback if multiline is not required.","Validate the env file locally before passing it to act."],"exampleFix":"# before (.env)\nSSH_KEY<<EOF\n-----BEGIN KEY-----\n# after (.env)\nSSH_KEY<<EOF\n-----BEGIN KEY-----\n-----END KEY-----\nEOF","handlingStrategy":"validation","validationCode":"func validateEnvHeredocs(path string) error {\n  f, _ := os.Open(path)\n  defer f.Close()\n  s := bufio.NewScanner(f)\n  var open string\n  for s.Scan() {\n    line := s.Text()\n    if open != '' {\n      if line == open { open = '' }\n      continue\n    }\n    if i := strings.Index(line, '<<'); i >= 0 {\n      open = strings.TrimSpace(line[i+2:])\n    }\n  }\n  if open != '' { return fmt.Errorf('unterminated delimiter %q', open) }\n  return nil\n}","typeGuard":null,"tryCatchPattern":"if err := parseEnvFile(e, path, &env)(); err != nil {\n  if strings.Contains(err.Error(), 'delimiter') { /* fix env file heredoc */ } else { return err }\n}","preventionTips":["Always close heredoc blocks with the exact delimiter line","Use LF line endings in .env files","Keep heredoc terminators at column 0 with no trailing spaces"],"tags":["env-file","parsing","heredoc","configuration"],"backgroundTag":null,"analyzedSha":"4f411281417e88660bea1c1a1749aa71ae0bd60f","analyzedAt":"2026-08-15T09:19:46.307Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}