Issue #3624394: Say where a plugin subform's validation error goes, so the next one does not name it
Fixes #3624394.
Every plugin that has reported a refusal from a settings subform named the error instead of setting it on the element, and the key that builds does not reach the field: EntityInteraction (form_operation), WebformInteraction (mode and context_display), and the Groups audience from #3624219, which was written the same way before an audit caught it. Two of them carried a comment asserting the opposite. #3624283 fixed the behaviour. This is about why it kept happening.
The rule had no home
docs/extending.md is the page that tells you how to write an audience, a condition, a task type and their settings forms. It did not mention setError, validateConfigurationForm or #parents once. The only statements of the rule were three copies of the same seven-line comment, each inside a plugin that had already learned it the hard way.
It now carries a Refusing a setting section under Plugin types, with the two calls side by side:
$form_state->setError($form['mode'], $message); // finds the field
$form_state->setErrorByName('mode', $message); // reaches nothingand why: an error is matched to its element by #parents, SubformState::setErrorByName() builds the name from #array_parents, and the classic modeler renders every node one level deeper than it submits it, so a name-built error belongs to no element on the page.
And the three comments are now one sentence each
Three copies of an explanation is a rule with two places to go stale. Each site now says what to do and points at the page for why.
Scope
Comments and documentation only. git diff -U0 -- '*.php' over the branch produces no changed line that is not a comment, so nothing here can alter behaviour and nothing needs a new test; the five classes covering these three plugins pass unchanged.
AI-Generated: Yes (Claude Code was used to help write this change and its description. I reviewed the work; every claim in the new passage was verified against core and against OrchestraCmForm while fixing #3624283, rather than asserted.)