Skip to content

fix: heredocs_to_strings writes a value, not the heredoc's text (#337) - #351

Draft
livingstaccato wants to merge 1 commit into
amplify-education:mainfrom
livingstaccato:fix/heredocs-to-strings-value
Draft

fix: heredocs_to_strings writes a value, not the heredoc's text (#337)#351
livingstaccato wants to merge 1 commit into
amplify-education:mainfrom
livingstaccato:fix/heredocs-to-strings-value

Conversation

@livingstaccato

@livingstaccato livingstaccato commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Fixes #337.

What

The option converts a heredoc into a quoted string, and was quoting the heredoc's own source — markers and all — across as many physical lines as the original occupied:

a = "<<EOT
hello
EOT"

A quoted template cannot span lines. OpenTofu rejects that with "Invalid multi-line string", and reading it back here gives '<<EOT\nhello\nEOT' — the marker text rather than the value. So the option produced neither a valid file nor the right content, and it is exposed on the shipped jsontohcl2 script, so the CLI had the same hole.

After:

a = "hello"

How

By reusing the flattening the reader already performs, rather than writing a second one: serializing the rule with preserve_heredocs=False is exactly the quoted form that option produces on the way in. The two therefore cannot drift apart the way the escape alphabets did in #329 — there is only one implementation of "what is this heredoc as a quoted string".

What that inherits

The value carried is the reader's. On main that still drops the body's trailing newline, so <<EOT\nhello\nEOT becomes "hello" where Terraform reads "hello\n". That is #326, fixed in #335, and this change deliberately follows whatever the reader does rather than second-guessing it — when #335 lands, this output gains the newline with no change here.

Eight tests, including that every converted form parses again and that no marker survives into the output.

Merging

It touches the same code as #346 (hcl2/deserializer.py), #354 (hcl2/deserializer.py). Whichever of those lands first, this one needs a rebase rather than a merge — the overlaps are real edits to the same methods, not adjacent lines, so resolving them by hand risks losing one of the two fixes. Say the word and I will rebase and re-run the suite.


This pull request, and the investigation behind it, were produced by an AI assistant (Claude) working on behalf of the author. Every reproduction, test run and benchmark cited was executed rather than inferred, but please review with that provenance in mind.

…ify-education#337)

The option converts a heredoc into a quoted string, and was quoting the
heredoc's own source -- markers and all -- across as many physical lines
as the original occupied:

    a = "<<EOT
    hello
    EOT"

A quoted template cannot span lines. OpenTofu rejects that with "Invalid
multi-line string", and reading it back here gave the marker text rather
than the value, so the option produced neither a valid file nor the
right content. It is exposed on the shipped `jsontohcl2` script, so the
CLI had the same hole.

The flattening the reader already performs is reused rather than written
a second time: serializing the rule with `preserve_heredocs=False` is
exactly the quoted form that option produces on the way in, so the two
cannot drift apart the way the escape alphabets did.

The value that form carries is the reader's, which on this branch still
drops the body's trailing newline -- that is amplify-education#326, and this change
follows whatever the reader does rather than second-guessing it.
@livingstaccato

Copy link
Copy Markdown
Contributor Author

Please hold off on merging this one for now — I want to do another review pass over it before it goes in. Opened as a draft for that reason; I will mark it ready and say so here once I am done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

heredocs_to_strings=True emits a multi-line quoted string, which is not valid HCL

1 participant