#10500·nocobase

Filter form issue on V2 menu (modern page)

Author: pehuaCreated Sep 12, 2026Updated Sep 14, 2026
<!-- First off, thank you for reporting bugs. Please do not clear the contents of the issue template. Items marked with * are required. Issues not filled out according to the template will be closed. Please communicate in English, and post content in other languages to NocoBase Forum https://forum.nocobase.com/. Non-English issues will be closed. -->

* Describe the bug

<!-- A clear and concise description of what the bug is. -->

The $includes filter operator returns inconsistent, incorrect results when the search string contains more than one word, on a field with interface: textarea (Multiline text, underlying type: text):

json
{
  "name": "req_descripcion_corta",
  "type": "text",
  "interface": "textarea",
  "uiSchema": {
    "x-component": "Input.TextArea",
    "title": "Descripción corta",
    "type": "text"
  }
}
  • A single-word $includes search on this field works correctly.
  • A multi-word $includes search on the same field is unreliable: in some cases it returns zero results even when the search string is an exact, literal copy of an existing record's field value; in other cases it returns far more rows than expected, including unrelated records that clearly do not contain that phrase.
  • There is no consistent pattern between the two failure modes (same operator, same field, same collection — only the specific phrase changes which failure mode appears).
  • Splitting the phrase into one $includes condition per word, combined with $and, returns the correct results — this is currently used as a workaround.

* Environment

<!-- Please view it by clicking on the ? icon in the upper right corner of the NocoBase navigation bar. -->
  • NocoBase version:2.2.4
<!-- [e.g. PostgreSQL 12, MySQL 8.x, SQLite] -->
  • Database type and version: PostgreSQL 16
<!-- [e.g. MacOS, Windows] -->
  • OS: Linux (self-hosted)
<!-- Docker, Create-nocobase-app, Git source code -->
  • Deployment Methods:create nocobase
<!-- If using Docker for deployment, please provide. [e.g. nocobase/nocobase:latest] -->
  • Docker image version:
<!-- If using Create-nocobase-app or Git source code for deployment, please provide. -->
  • NodeJS version:22.17

* How To Reproduce

<!-- Please describe the reproduction process in as much detail as possible. -->
  1. Filter with a single word:

    json
    { "req_descripcion_corta": { "$includes": "CHAPA" } }
    

    → Returns correct matching rows, e.g. a row whose field value is exactly "COJINETES DE LA CHAPA TRANSPORTADORA".

  2. Copy that exact, literal value from the matched row and filter with it:

    json
    { "req_descripcion_corta": { "$includes": "COJINETES DE LA CHAPA TRANSPORTADORA" } }
    

    → Returns 0 results, even though this string is not just a substring but the entire, exact value of the field on an existing row.

  3. Try the same string wrapped in literal escaped quotes (in case the API expects a quoted phrase for exact matching):

    json
    { "req_descripcion_corta": { "$includes": "\"COJINETES DE LA CHAPA TRANSPORTADORA\"" } }
    

    → Still 0 results.

  4. On a different, shorter multi-word string:

    json
    { "req_descripcion_corta": { "$includes": "PINCEL Nro" } }
    

    → Returns a very large result set, including many unrelated "PINCEL" variants that do not contain that exact phrase.

  5. Adding a third word narrows it slightly but it is still overly broad:

    json
    { "req_descripcion_corta": { "$includes": "PINCEL Nro 20" } }
    

    → Still returns far more rows than a literal substring match should.

  6. Workaround that does work — split the phrase into one $includes condition per word, joined with $and:

    json
    {
      "$and": [
        { "req_descripcion_corta": { "$includes": "CHAPA" } },
        { "req_descripcion_corta": { "$includes": "TRANSPORTADORA" } }
      ]
    }
    

    → Returns the expected, correct results.

All requests above were run against the same collection (gestionrc), same field (req_descripcion_corta), through the standard Table block search filter, with an additional $and base filter on planta/empresa present in every request (constant across all of them, not a variable).

Expected behavior

<!-- A clear and concise description of what you expected to happen. -->

A multi-word $includes filter should behave as a plain substring search: at minimum, it should always match a record when the search string is an exact copy of that record's field value. Behavior should not flip between "zero results" and "too many results" depending on the specific phrase — and it definitely should not return zero results for a phrase that is a verbatim copy of the stored value.

Screenshots

<!-- If applicable, add screenshots to help explain your problem. --> Image Image Image

Logs

<!-- If it's an API error, please provide the relevant server logs. -->

bodySize is the response payload size in bytes; 68 corresponds to an empty result set (no matching rows).

Filter ($includes value) | Result -- | -- "CHAPA" | Correct matches (baseline, works) "CHAPA TRANSPORTADORA" | bodySize=68 (empty) "COJINETES DE LA CHAPA TRANSPORTADORA" (exact literal field value) | bodySize=68 (empty) "\"COJINETES DE LA CHAPA TRANSPORTADORA\"" (same, quoted) | bodySize=68 (empty) "PINCEL Nro" | bodySize=106922 (far too broad) "PINCEL Nro 20" | bodySize=28735 (still too broad)

Example raw request log line (empty-result case):

response /noco/api/gestionrc:list?filter=...&sort[]=-req_numero&page=1&pageSize=100&tree=false
res={"status":200}
action={"actionName":"list","resourceName":"gestionrc","params":{"filter":{"$and":[{"$and":[{"planta":{"$eq":2}},{"empresa":{"$includes":"213"}}]},{"empresa":{"$includes":"213"}},{"req_descripcion_corta":{"$includes":"COJINETES DE LA CHAPA TRANSPORTADORA"}}]},"sort":["-req_numero"],"page":"1","pageSize":"100","tree":"false","resourceName":"gestionrc","actionName":"list","values":{}}}
status=200 bodySize=68