fix: #3583083 State the entity input violation's reason only and let Drush add its own advice
Closes #3583083 (closed)
The "must be an entity" violation told every invoker without InvokerCapability::EntitiesAsHandles that it cannot pass entities and should look for a tool that takes an entity type and ID (#3583046 (closed)). That capability is the switch for Tool API's own handle subscriber, not a statement about what an invoker can deliver: input transforms are an open event, so any module can turn what an invoker sent into an entity, and an in-process invoker such as eca_tool's hands tools real entity objects. Validation cannot know the answer in either polarity, so it stops guessing.
TypedInputsTraitstates the reason only,This input must be an entity., for every invoker, with the input on the property path as for every other violation (#3583085 (closed)). The capability check and the invoker-named hint are gone.- The violation carries a code,
TypedInputsInterface::NOT_AN_ENTITY_ERROR, so an invoker can add advice of its own by matching the code rather than the message or the input's type. The code survives the rebuilds that put a list item's or map property's position on the path. drush tool:run, which passes only strings and JSON, adds its own line after the violations when one carries that code:drush tool:run cannot pass entities; use a tool that takes an entity type and ID instead.A missing required entity input, or a constraint failure on a value something did turn into an entity, gets no such line..agents/skills/use-drupal-tools/SKILL.mdshows the current Drush output for an entity input.- No new
InvokerCapabilitycase: the earlierEntitiesAsObjectsapproach on this branch is reverted, soInvoker,tool.api.phpand the entity handles docs are unchanged.
Tests: EntityInputTypeCheckTest::testEntityViolationIsTheReasonForEveryInvoker (no invoker, an invoker with no capabilities, a handle-capable invoker: the same message and code, and the code on a list item's violation) and ToolRunCommandTest::testEntityViolationNamesTheWorkaround (the reason on the entity: path plus the command's advice, and no advice for a violation on a non-entity input).
Release note: The "This input must be an entity." violation no longer names the invoker or suggests another tool; it carries the code TypedInputsInterface::NOT_AN_ENTITY_ERROR. drush tool:run adds that advice itself for a value that is not an entity.