Skip to content

[FIXED] Accept {{left}} and {{right}} mapping functions in ValidateMapping - #8568

Merged
neilalexander merged 1 commit into
nats-io:mainfrom
winklemad:fix/validate-mapping-left-right
Sep 8, 2026
Merged

neilalexander merged 1 commit into
nats-io:mainfrom
winklemad:fix/validate-mapping-left-right

Conversation

@winklemad

Copy link
Copy Markdown
Contributor

Problem

The left and right mapping functions were added to the subject transform in #5337 and announced in the 2.10.16 release notes, but the allowlist in ValidateMapping (server/sublist.go) was never updated. It still lists the other eight functions, so a destination using {{left(...)}} or {{right(...)}} is rejected with invalid mapping destination: unknown function.

That blocks them on the path they were added for. #5337's own description uses account-mapping config syntax (foo.*: foo.{{Right(1,2)}}), and that config does not load:

Error adding mapping for "foo.*" to "bar.{{right(1,2)}}" : invalid mapping destination: unknown function in {{right(1,2)}}

The server refuses to start. The same applies to Account.AddMapping and to a stream subject_transform, mirror or source transform, which fail with JSStreamTransformInvalidDestinationError (10156).

Meanwhile RePublish and nats server mapping call NewSubjectTransform directly and accept the very same destination, and the transform itself works correctly (foo.1234 -> bar.34). So the function is implemented and shipped, just not reachable from config.

Change

Add the two regexes to the allowlist, the same way random was added in #6950 and split/slice in #3305. Two lines.

Tests: the left/right cases in TestValidateDestinationSubject (I also added slice, split and random there, which were untested), and TestAccountLeftRightMapping, which loads a config with both functions and checks the mapped subjects arrive as bar.34 and qux.123. Both fail on main.

One alternative worth mentioning: the allowlist looks redundant now. Since #5617 ValidateMapping ends with a NewSubjectTransform call, and indexPlaceHolders already returns ErrUnknownMappingDestinationFunction for an unknown function, so removing the eight regexes would give the same errors from a single source of truth and this class of drift could not happen again. I went with the smaller change to match precedent, but happy to switch if you prefer that.

Not addressed here: left/right mappings pushed through JWT claims currently disappear silently because AddWeightedMappings' error is discarded (#8468 / #8473). That is a separate defect.

The subject transform has supported the left and right mapping functions
since 2.10.16 (nats-io#5337), but the allowlist in ValidateMapping was never
updated, so it rejects them with "unknown function".

That makes them unusable on the path they were added for: a config file
with an account mapping using {{right(1,2)}} fails to load and the server
refuses to start, and a stream subject_transform is rejected with error
10156. The same destination is accepted by RePublish and by
"nats server mapping", which call NewSubjectTransform directly.

Add the two regexes to the allowlist, the same way random was added in
nats-io#6950. As an alternative, the allowlist could be dropped altogether:
ValidateMapping has ended with a NewSubjectTransform call since nats-io#5617,
and the parser already returns ErrUnknownMappingDestinationFunction for
an unknown function. Happy to do that instead if you prefer it.

Signed-off-by: Madan Kumar <[email protected]>
@winklemad
winklemad requested a review from a team as a code owner September 4, 2026 18:15
@MauriceVanVeen

Copy link
Copy Markdown
Member

@claude, brief review.

@synadia-claude-reviewer

synadia-claude-reviewer Bot commented Sep 7, 2026 •

Copy link
Copy Markdown

Claude finished @MauriceVanVeen's task in 59s —— View job


Brief Review

  • Read changed files and diff
  • Analyze the fix in server/sublist.go
  • Review test coverage
  • Post review findings

Fix is correct and minimal. The two regexes (leftMappingFunctionRegEx, rightMappingFunctionRegEx) were already defined and used in server/subject_transform.go (lines 37–38) since #5337 — they just weren't wired into the allowlist in ValidateMapping. The two-line addition in server/sublist.go:1291-1292 exactly mirrors how randomMappingFunctionRegEx was added in #6950, consistent with the existing pattern.

Test coverage is solid:

  • sublist_test.go: 9 new cases in TestValidateDestinationSubject cover lowercase, uppercase (Left/Right), whitespace tolerance, and the four previously-untested functions (SliceFromLeft, SliceFromRight, split, random).
  • accounts_test.go: TestAccountLeftRightMapping is a good end-to-end integration test — it boots an actual server from config, publishes through the mapping, and asserts the transformed subjects (bar.34, qux.123).

One minor note: the whitespace test {{ left( 1 , 2 ) }} passes through ValidateMapping's allowlist (the regex handles \s*), but it's worth confirming NewSubjectTransform at the end of ValidateMapping also tolerates that whitespace — though given {{ left( 1 , 2 ) }} is a realistic user mistake and the regex accepts it, this is probably fine as-is.

The alternative the author raised (dropping the allowlist entirely since ValidateMapping already ends with NewSubjectTransform) is worth considering for maintainability — this class of drift (#5337 shipped the function, the allowlist wasn't updated, two releases later it's caught) couldn't happen again. But that's a bigger refactor and the minimal fix is clean.

Overall: looks good to merge.

@MauriceVanVeen MauriceVanVeen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@neilalexander
neilalexander merged commit 86b92e5 into nats-io:main Sep 8, 2026
45 of 46 checks passed
@winklemad

Copy link
Copy Markdown
Contributor Author

Thanks @MauriceVanVeen!

neilalexander added a commit that referenced this pull request Sep 10, 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.

3 participants