Skip to content

fix(agent): refuse a single-record action given several records [PRD-1704] - #417

Merged
matthv merged 3 commits into
mainfrom
feature/prd-1704-a-single-record-action-given-several-records-runs-on-the
Oct 23, 2026
Merged

matthv merged 3 commits into
mainfrom
feature/prd-1704-a-single-record-action-given-several-records-runs-on-the

Conversation

@hercemer42

@hercemer42 hercemer42 commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

A single-record action triggered on several record ids now answers 422 ("This action can only be triggered on one record at a time.") instead of running on the first record and answering success. Same fix as the Node agent, ForestAdmin/agent-nodejs#2028.

Refs: PRD-1704

What changes

  1. A single-record action on two or more ids. Before: the action ran on the first record only (ActionContextSingle#get_record reads get_records[0]) and answered success, so the other records were skipped and nobody was told. After: 422, and nothing runs.
  2. The same request on an action that requires approval. Before: the agent asked for an approval, which later ran on the first record only. After: 422 at submit time, before the permission check, so no approval is asked for. Approving a request already stored with several ids answers 422 too.
  3. A single-record action on a select-all selection. Before: it ran on whichever record came first. After: 422. The UI already disables single-record actions on a select-all, so it never sends this.
  4. Loading a single-record action's form with several ids (/hooks/load, /hooks/change, /hooks/search). Before: the form loaded against the first record. After: 422.

A single-record action on exactly one id, and bulk and global actions, behave as before; a spec now pins the one-id case.

Definition of Done

General

  • Write an explicit title for the Pull Request, following Conventional Commits specification
  • Test manually the implemented changes
  • Validate the code quality (indentation, syntax, style, simplicity, readability)

Security

  • Consider the security impact of the changes made

Squash message

fix(agent): refuse a single-record action given several records [PRD-1704]

A single-record action triggered on several record ids ran on the first
record only and answered success, skipping the others silently; approving
an approval request naming several ids did the same.

The action route now answers 422 for a single-record action whose
selection names more than one id or is a select-all, before the
permission check, on execute and on the form hooks alike.

🤖 Generated with Claude Code

Note

Reject multi-record selections for SINGLE-scope actions in Actions routes

  • Adds Routes::Action::Actions.ensure_single_record, which raises UnprocessableError when a SINGLE-scope action receives more than one ID or a select-all/exclusion selection.
  • The check runs in get_record_selection right after parsing selection IDs, before condition-tree building, related-data filtering, permission approval, and form loading.
  • Adds specs covering rejection of two IDs, select-all, and signed approval requests, plus successful execution with exactly one ID.
  • Behavioral Change: requests that previously continued with multi-record selections on SINGLE actions now get a 422 error instead.

Changes since #417 opened

  • Modified ForestAdminAgent::Routes::Action::Actions.ensure_single_record to reject selections that do not contain exactly one record ID for SINGLE-scope actions [e92ccd1]
  • Added test coverage for empty selection rejection in SINGLE-scope action validation [e92ccd1]

Macroscope summarized 13185c0.

…1704]

A single-record action triggered on several ids ran on the first record
only and answered success, since ActionContextSingle#get_record reads the
first record. An API client, an MCP call or an approval request could send
such a selection, and every record past the first was silently skipped.

The action route now answers 422 for a single-record action whose
selection names more than one id or is a select-all, before the
permission check: no approval is asked for, approving a stored request
runs nothing, and the form hooks refuse it too. Same fix as the Node
agent (ForestAdmin/agent-nodejs#2028).

Refs: PRD-1704

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@qltysh

qltysh Bot commented Oct 21, 2026

Copy link
Copy Markdown

Qlty


Coverage Impact

This PR will not change total coverage.

Modified Files with Diff Coverage (1)

RatingFile% DiffUncovered Line #s
Coverage rating: A Coverage rating: A
...st_admin_agent/lib/forest_admin_agent/routes/action/actions.rb100.0%
Total100.0%
🚦 See full report on Qlty Cloud »

🛟 Help
  • Diff Coverage: Coverage for added or modified lines of code (excludes deleted files). Learn more.

  • Total Coverage: Coverage for the whole repository, calculated as the sum of all File Coverage. Learn more.

  • File Coverage: Covered Lines divided by Covered Lines plus Missed Lines. (Excludes non-executable lines including blank lines and comments.)

    • Indirect Changes: Changes to File Coverage for files that were not modified in this PR. Learn more.

@linear-code

linear-code Bot commented Oct 21, 2026

Copy link
Copy Markdown

PRD-1704

@hercemer42 hercemer42 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Spec (PRD-1704): conforms.

…vate decoder [PRD-1704]

Refs: PRD-1704

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@matthv matthv left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Spec (PRD-1704): conforms.

Comment thread packages/forest_admin_agent/lib/forest_admin_agent/routes/action/actions.rb Outdated
The route refused a single action on several ids or a select-all but
let an empty selection through: the action then ran on a match_none
filter and answered success, or raised on a nil record. A single action
now runs only on exactly one id, as the Node and Python agents do.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

@Scra3 Scra3 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Approved after /validator run 417-20261022165454-Scra3: nothing blocking posted, 0 preferential or code style, 0 suppressed below all.

@matthv
matthv merged commit cdbbc7b into main Oct 23, 2026
31 checks passed
@matthv
matthv deleted the feature/prd-1704-a-single-record-action-given-several-records-runs-on-the branch October 23, 2026 07:44
forest-bot added a commit that referenced this pull request Oct 23, 2026
## [1.46.4](v1.46.3...v1.46.4) (2026-10-23)

### Bug Fixes

* **agent:** refuse a single-record action given several records [PRD-1704] ([#417](#417)) ([cdbbc7b](cdbbc7b))
@forest-bot

Copy link
Copy Markdown
Member

🎉 This PR is included in version 1.46.4 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants