Skip to content

fix: parse identifiers with leading underscores - #369

Draft
joaothallis wants to merge 2 commits into
developfrom
fix/leading-underscore-identifiers
Draft

fix: parse identifiers with leading underscores#369
joaothallis wants to merge 2 commits into
developfrom
fix/leading-underscore-identifiers

Conversation

@joaothallis

Copy link
Copy Markdown
Contributor

Problem

WhatsApp webhook payloads carry vendor keys that start with an underscore, such as _vnd. Expressions traversing them stopped parsing at the underscore:

Expression.evaluate_as_string!("@event.message._vnd.v1.chat", context)
# => "%{\"_vnd\" => %{...}}._vnd.v1.chat"
#    (the inspected message map, then the rest as literal text)

The atom combinator in Expression.Parser required the first character of an identifier to be a letter or digit, so ._vnd failed the attribute parse and the expression was truncated after event.message. These keys come from the platform's own webhook enrichment, so flow authors cannot rename them; the only workaround was bracket syntax (@event.message["_vnd"]["v1"]["chat"]).

Fix

Allow leading underscores in the atom grammar while still requiring at least one letter or digit, so a bare _ keeps failing to parse (@(_) remains literal text, pinned by an existing test).

Behavior changes

Input Before After
@event.message._vnd.v1.chat truncated after event.message, tail rendered as literal text resolves the full chain
@_missing (not in context) rendered _missing — the @ was silently swallowed by an empty expression match rendered @_missing, the documented round-trip for unresolved variables
@(_) literal, no expression parsed unchanged

Tests

  • Parser: @_foo / @__foo as variables, @event.message._vnd.v1.chat attribute chain, @(foo._bar) block form
  • Evaluation: resolving through _vnd-style nested keys as string and block, unresolved @_missing round-trip
  • Full suite: 688 passed, mix format and mix credo --strict clean

🤖 Generated with Claude Code

joaothallis and others added 2 commits August 3, 2026 22:33
WhatsApp webhook payloads carry vendor keys such as _vnd, so journey
expressions like @event.message._vnd.v1.chat must resolve. The atom
grammar rejected underscores in the first position, truncating the
expression at the first underscore-leading attribute and leaving the
rest as literal text.

A bare _ still does not parse as an identifier, so @(_) remains
literal text as before.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@joaothallis joaothallis self-assigned this Aug 4, 2026
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.

1 participant