Skip to content

docs(search): document the field selection form and the extended search refusal - #29

Open
PMerlet wants to merge 2 commits into
mainfrom
docs/search-extended-search-permission-check
Open

docs(search): document the field selection form and the extended search refusal#29
PMerlet wants to merge 2 commits into
mainfrom
docs/search-extended-search-permission-check

Conversation

@PMerlet

@PMerlet PMerlet commented Aug 27, 2026

Copy link
Copy Markdown
Member

Why

@forestadmin/agent 1.97.3 shipped ForestAdmin/agent-nodejs#1840, which refuses an extended search whenever the agent cannot enumerate the fields the search reads. A replaceSearch handler prevents that enumeration, so every collection with a custom search handler now returns a 403 on extended search.

Nothing on the search page said so — and every Node.js example on it used the handler form. A customer following the documentation was walking into the failure.

It shipped as a patch, with no BREAKING marker anywhere in the changelog, so the page is the main place a customer would find out.

What changed

product/build/search-configuration.mdx:

  • How Search Works — the extended search bullet now states the permission check and the enumeration requirement.
  • Replacing the Search Handler — a table of the two forms and what each costs, plus a <Warning> quoting the actual error message and naming the versions.
  • Restricting Which Fields Are Searched and Excluding Fields from Default Search — the Node.js examples now use the field selection form from ForestAdmin/agent-nodejs#1852 (replaceSearch({ onlyFields: [...] })), which the agent enumerates and permission-checks, so extended search keeps working. includeFields and relation paths documented alongside.
  • Context-Dependent Search and Integrating an External Search Engine — these genuinely need a handler, so they keep it and now say what it costs.
  • Limitations — added, with the per-agent matrix and the version requirements.

reference/agent-api/nodejs.mdx:

  • collection.replaceSearch now documents both forms, the three field-selection options as a table, and the extended-search consequence.

The example that had become self-contradicting

Worth a reviewer's eye. Context-Dependent Search branches on extendedMode to pick its onlyFields:

if (!extendedMode)
  return context.generateSearchFilter(searchString, { onlyFields: ['name'] });

return context.generateSearchFilter(searchString, {
  onlyFields: ['name', 'description', 'brand:name'],
});

Because it installs a handler, the agent refuses the extended search before the handler runs. Its extended branch has been unreachable since 1.97.3. The page now says so rather than leaving the example looking functional. The Ruby version of the same example still reaches its branch.

Cross-agent accuracy

Scoped to Node.js throughout, checked against each SDK rather than assumed:

Agent Field selection form Extended search with a handler
Node.js ≥ 1.98.3 Available Refused (403)
Node.js 1.97.3–1.98.2 Not available Refused (403)
Node.js < 1.97.3 Not available Served
Ruby Not available Served, uncheckedcollect_search_usages returns early on an unknown footprint instead of refusing
Python Not available Served — the read-permission check on related collections is not implemented

The Ruby row is a gap rather than a design choice: the extended-search half of the disclosure #1840 closed is still open there. That belongs in a ticket on agent-ruby, not in this PR, and I have not opened one yet.

Also worth flagging, outside this PR

A customer whose handler is genuinely custom — an external index, a filter derived from the search string — has no migration path. Extended search stays refused for them, and the only alternatives are disableSearch() or dropping their custom search. Letting a handler declare its own footprint would fix that and needs a change in agent-nodejs.

🤖 Generated with Claude Code

Note

Document replaceSearch field selection form and extended search 403 refusal

  • Documents the two forms of replaceSearch in Node.js: field selection (SearchFieldsDefinition) and handler (SearchHandlerDefinition), with a comparison table in search-configuration.mdx
  • Explains that from @forestadmin/agent 1.97.3+, using a handler causes extended search to return 403 because the agent cannot enumerate read fields ahead of the query; normal search still works
  • Rewrites Node.js examples to use the field selection object form (onlyFields, excludeFields) instead of a handler returning context.generateSearchFilter
  • Documents relation path syntax, resolution rules (ManyToOne/OneToOne/OneToMany resolve; ManyToMany paths dropped silently), and permission checks at the terminal collection
  • Adds a Limitations section covering version requirements (field selection requires datasource-customizer 1.71.3+, shipped in agent 1.98.3), cross-language behavior differences, and handler exemption from read-permission checks on normal search
  • Updates the API reference in nodejs.mdx with the dual-form signature, field selection options, and the 403 warning for handler-based extended search

Macroscope summarized 1b9d8ba.

…ch refusal

The Node.js agent has refused extended search on any collection with a
`replaceSearch` handler since 1.97.3, because it cannot enumerate the fields a
handler reads and so cannot check them against the caller's read permission.
Nothing on the search page said so, and every Node.js example on it used the
handler form.

The two `onlyFields` / `excludeFields` examples now use the field selection form
that 1.71.3 introduced, which the agent can enumerate and permission-check, so
extended search keeps working. The two remaining handler examples keep their
handler and say what it costs — the Context-Dependent Search example in
particular, whose `extendedMode` branch has been unreachable since 1.97.3.

Scoped to Node.js throughout: Ruby serves an extended search on a handler
collection without checking it, and the Python agent has no such check at all.

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

mintlify Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
forest 🟢 Ready View Preview Aug 27, 2026, 12:52 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

Comment thread reference/agent-api/nodejs.mdx Outdated
Comment thread reference/agent-api/nodejs.mdx
…keover

Both raised by review on #29 and checked against agent-nodejs:

- `lenientGetSchema` resolves a path segment only through `ManyToOne`,
  `OneToOne` and `OneToMany`. A `ManyToMany` segment resolves to null and
  the path is filtered out, so `includeFields: ['tags:name']` searched
  nothing while the page claimed paths cross relations at any depth.
- `refineFilter` implements the search itself as soon as a replacer is set,
  so on a datasource that called `enableSearch()` a field selection does not
  narrow the native search, it replaces it with the agent's per-column one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.

1 participant