`ActionConfig.staticValidate` only ever inspected the singular `Query`
field, so any action defining the plural `queries` form failed startup
validation with "query is required" and blocked the sync entirely.
Both forms are already accepted by `ActionConfig.Validate` (which
enforces exactly-one-of) and by `handleQueryAction`, which executes
`Queries` when present. Only the static validator was out of step, so
this was a false positive on configs that would otherwise run fine.
Regression introduced in v0.5.0 by c3f62e1 (#98); v0.4.4 had no
`ActionConfig.staticValidate` at all, so the plural form worked by never
being checked.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Description
ActionConfig.staticValidateonly inspected the singularQueryfield, so any action defining the pluralqueriesform failed startup validation withquery is requiredand blocked the sync entirely:Both forms are already accepted by
ActionConfig.Validate(which enforces exactly-one-of,pkg/bsql/config.go:658) and byhandleQueryAction, which executesQuerieswhen present (pkg/connector/action.go:209). Only the static validator was out of step — a false positive on configs that would otherwise run fine.Regression window: introduced in v0.5.0 by c3f62e1 (#98). v0.4.4 had no
ActionConfig.staticValidateat all, so the plural form worked by never being checked. Affects v0.5.0 through v0.5.13.Reported by a customer upgrading service-mode baton-sql from v0.4.4 to v0.5.13 with a two-statement
account_disableaction.Testing
Three cases added to the table-driven
TestValidateinpkg/bsql/validate_test.go:action with queries— the regression pin. Fails against the parent commit with the exact customer-facing error (query is required), passes with the fix.action with singular query— guards the path the new branch could have bypassed.action with queries referencing undefined var— confirms the loop still validates each statement rather than short-circuiting after the first.go build ./...clean; full./pkg/...suite passes.Follow-up (not in this PR)
The error message blames a resource type (
resource type "user") for a top-levelactions:failure, because the action loop lives inside the per-resource-typeSQLSyncer.Validate(pkg/bsql/sql_syncer.go:149). This misattribution actively misleads — it sent the reporter looking for anactionsblock underresource_types.user, which doesn't exist.Useful links:
🤖 Generated with Claude Code