Skip to content

Regression in 8.x: empty heredoc fails to parse (regression of #101) #309

Description

@livingstaccato

Describe the bug

An empty heredoc fails to parse. This is a regression of #101 ("Unexpected token exception on empty heredoc"), fixed in 2023 and working in 7.2.1 (which returns '').

Software:

  • OS: macOS 15 (arm64)

  • Python version: 3.11.16

  • python-hcl2 versions tested, each in a clean isolated environment:

    • 7.2.1 — returns {'bar': ''}
    • 7.3.1 — returns {'bar': ''}
    • 8.0.0rc1 — raises
    • 8.1.0 — raises
    • 8.1.2 — raises

    So this arrived with the v8 rewrite rather than in a later 8.1.x change.

Snippet of HCL2 code causing the unexpected behaviour:

bar = <<EOF
EOF

Expected behavior (7.2.1)

{'bar': ''}

Exception traceback:

lark.exceptions.UnexpectedCharacters: No terminal matches '<' in the current parser context, at line 1 col 7

bar = <<EOF
      ^
Expected one of:
	* FLOAT_LITERAL
	* HEREDOC_TEMPLATE
	* MINUS
	...

followed by

lark.exceptions.UnexpectedToken: Unexpected token Token('STRING_CHARS', '<<EOF\nEOF\n\n') at line 1, column 7.

Root cause

In hcl2/hcl2.lark, the v8 HEREDOC_TEMPLATE terminal requires at least one body line: the \n? that used to follow the opening marker in 7.x is gone, so a marker immediately followed by the closing delimiter does not match and the input falls through to STRING_CHARS.

A heredoc whose body is a single empty line does parse, which makes the failing case look arbitrary:

>>> hcl2.loads("bar = <<EOF\n\nEOF\n")   # one blank line - OK
{'bar': '"<<EOF\n\nEOF"'}
>>> hcl2.loads("bar = <<EOF\nEOF\n")      # no body - raises

Impact

Generated configurations legitimately contain empty heredocs (an empty user-data script, an empty policy document), and a whole file fails to parse because of one.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinggrammarIssue is related to HCL2 grammar definitionregressionSomething broke in a new versionround-tripFull-cycle parse/serialize/deserialize fidelityunreleasedFix merged into main; waiting for version release

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions