Skip to content

0.17.1 nightlies remove #"…"# hash string literals (E0098) with no render-preserving migration path — the backtick replacement dedents indent-bearing prompt fragments #4591

Description

@BenSpex

Summary

0.17.1-nightly.20260824.b removes #"…"# hash string literals (error[E0098] removed language feature) with no migration path that preserves the rendered prompt:

  • baml fmt under the nightly does not migrate them — it exits 4 ("formatted 27 of 47 file(s); 20 failed") and leaves every hash literal in place (while reformatting the other 27 files, which is separate churn). There is no baml migrate command.
  • The obvious mechanical replacement — a multi-line backtick string — is not render-equivalent: backtick strings are dedented by their common indent, so an indent-bearing hash literal (used as a prompt fragment) renders differently after the rewrite.

Measured on a real prompt corpus (German insolvency platform, 47 .baml files)

  • Census: 358 hash literals across 20 files; 36 of them multi-line (indent is part of the render); 127 contain a backtick (needs escaping in the backtick form); 17 contain " (needs \" in the quoted form); 0 contain ${ or $ or \.
  • Naive #"…"# → backtick migration: baml check green, but 11 of 33 rendered prompts change — proven exactly: same line counts, 28 differing lines, all of the form old == " " + new (a 4-space common-indent dedent of shared number-format fragments).
  • A render-neutral migration exists: every hash literal becomes ONE double-quoted string with \\, \", \n escaped. baml check exit 0 on both 0.17.0 and the nightly, and 0/33 render diffs. Cost: a ~2.3 kB prompt block becomes one enormous single line — prompt review as prose becomes materially harder. No indent-preserving multi-line form survives common-indent dedent unless a line sits at column 0, which changes the render.

Why this matters

For a prompt-corpus consumer, "render-identical" is the difference between a mechanical toolchain upgrade and a re-verification of every prompt against a live model (recorded-eval re-record). We just paid the 0.15→0.17 migration with a per-function byte-level render differential to avoid exactly that; this removal forces the same exercise again, and the only render-safe target form is much less reviewable than what was removed.

Asks (either would resolve it)

  1. A migration mode — baml fmt --fix-removed-features or similar — that rewrites hash literals to a render-identical form automatically; or
  2. A raw multi-line string form that preserves indentation (no common-indent dedent), so indent-bearing prompt fragments have a faithful home.

Environment

baml wrapper 0.2.0; 0.17.0 (accepts hash literals) vs 0.17.1-nightly.20260824.b (E0098); Linux x86_64. Related context from this consumer: #4588 (fixed on this nightly — thank you), #4589/#4590 (still reproduce on it), #4370.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions