diff --git a/CHANGELOG.md b/CHANGELOG.md index 048c1aa5..9fe80d63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Fix unsafe concurrent producer map access in client. [PR #1236](https://github.com/riverqueue/river/pull/1236). +- Fix bug in `sqltemplate` cached path in order in which named args are passed to a query (previously, the order was unstable). [PR #1243](https://github.com/riverqueue/river/pull/1243). ## [0.35.1] - 2026-04-26 diff --git a/rivershared/sqlctemplate/sqlc_template.go b/rivershared/sqlctemplate/sqlc_template.go index 88c02edb..1151b7d1 100644 --- a/rivershared/sqlctemplate/sqlc_template.go +++ b/rivershared/sqlctemplate/sqlc_template.go @@ -156,7 +156,14 @@ func (r *Replacer) RunSafely(ctx context.Context, argPlaceholder, sql string, ar // If all input templates were stable, the finished SQL will have been cached. if cachedSQLOK { if len(container.NamedArgs) > 0 { - args = append(args, maputil.Values(container.NamedArgs)...) + // Named args must be appended in sorted order to match the + // placeholder positions baked into the cached SQL during + // RunSafely's cache miss path. + sortedNamedArgs := maputil.Keys(container.NamedArgs) + slices.Sort(sortedNamedArgs) + for _, name := range sortedNamedArgs { + args = append(args, container.NamedArgs[name]) + } } return cachedSQL, args, nil }