Why this fires¶
<style> and <script> are raw text elements: once the parser sees the opening tag, everything up to the matching </style> or </script> is taken verbatim as the element's content — literal CSS or JavaScript text. No nested markup is recognized, no {expr} interpolation runs, and no entity is decoded. The only thing that can end the block is the exact closing tag.
TE139 fires when the file ends before that closing tag shows up. The two common causes:
- The closing tag was simply forgotten.
- A
</styleor</script-shaped sequence appears inside the content — most often a JavaScript string containing"</script>"— and the parser (correctly, per the raw-text rule) treated it as the close, then ran out of file looking for a second one.
fn page() -> Element {
return <div>
<style>
.card { padding: 8px }
</div>
// ^ error[TE139]: unclosed `<style>`: a raw text element's content runs
// until `</style>`, and none was found before the end of the file.
}Fix it¶
1. Close the block¶
<style>
.card { padding: 8px }
</style>2. Escape a closing sequence that must appear inside JavaScript content¶
A JS string containing the literal text </script> closes the block early, exactly the way it does in HTML:
<script>
console.log("</script>") // closes the block here — TE139 on whatever follows
</script>Split the sequence so the raw-text scanner doesn't recognize it:
<script>
console.log("<\/script>") // ok — no longer a literal `</script>` in the source text
</script>See also¶
- Ordinary elements report a different, generic message when unclosed (
unclosed elementwith no code) —<style>/<script>getTE139specifically because the raw-text rule (verbatim content, no nested markup) makes the fix different from a missing</div>.