Skip to content

Invoke Validate() on embedded structs and plugin elements#607

Merged
alecthomas merged 1 commit into
alecthomas:masterfrom
costela:fix-validate-embed-and-plugins
Jun 26, 2026
Merged

Invoke Validate() on embedded structs and plugin elements#607
alecthomas merged 1 commit into
alecthomas:masterfrom
costela:fix-validate-embed-and-plugins

Conversation

@costela

@costela costela commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Summary

Context.Validate iterates c.Path and calls isValidatable on each entry's target. Fields tagged embed:"" are flattened into their parent at build time and have no path entry, so any Validate() method on the embedded struct itself was never invoked. The same issue affects kong.Plugins, whose elements are also flattened.

  • Extracted the embedded-field walk that already existed in getMethods into a shared walkEmbedded helper, used by both hooks (getMethods) and validators (new getValidators), so the rules for "what counts as embedded" live in one place.
  • walkEmbedded also descends into Plugins elements, matching what flattenedFields does in build.go. This incidentally fixes the same latent bug for hooks on plugin structs.

Test plan

  • TestValidateEmbedValidate() on a struct tagged embed:"" at the app root
  • TestValidateEmbedOnCommand — same, nested under a command (verifies the cmd: prefix)
  • TestValidateNestedEmbed — recursive embed-within-embed
  • TestExtendedValidateEmbed — the Validate(kctx *Context) error variant
  • TestValidatePluginValidate() on a struct registered via kong.Plugins
  • go test ./... and golangci-lint run pass

This fixes #554

Context.Validate iterated c.Path and called isValidatable on each
entry's target. Fields tagged embed:"" are flattened into their parent
at build time and have no path entry, so any Validate() method on the
embedded struct itself was never invoked. The same issue affects
kong.Plugins, whose elements are also flattened.

Extracts the embedded-field walk that already existed in getMethods
into a shared walkEmbedded helper, used by both hooks (getMethods) and
validators (new getValidators), so the rules for "what counts as
embedded" live in one place. walkEmbedded also descends into Plugins
elements, matching what flattenedFields does in build.go — this
incidentally fixes the same latent bug for hooks on plugin structs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@alecthomas alecthomas left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Love it, thanks!

@alecthomas alecthomas merged commit 59826d1 into alecthomas:master Jun 26, 2026
5 checks passed
@costela

costela commented Jun 26, 2026

Copy link
Copy Markdown
Contributor Author

@alecthomas Thanks for the quick merge! 🙏 🚀

If it's not too much to ask, it would be great if we could also get a tag with it? 😇
(and maybe include the many times forgotten #588 as well? 🙈)

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.

Custom validator does not run for embedded structs

2 participants