Describe the bug
POST /api/v1/accounts/{id}/contacts/filter returns HTTP 500 when filtering a text-type custom attribute with a JSON numeric value. The same filter with the value as a JSON string works correctly.
This bites hardest through the dashboard: when an agent types a digits-only value (e.g. a national ID stored as a text custom attribute) into the contacts filter, the request can fail — and the UI does not surface the error. It keeps showing the previous unfiltered contact list with the filter chip applied, which reads as "these contacts matched", so agents trust a wrong result.
To Reproduce
- Create a contact custom attribute of display type
text (e.g. key cpf).
- Filter contacts by it with a numeric JSON value:
curl -X POST "https://<host>/api/v1/accounts/1/contacts/filter" \\
-H "api_access_token: <token>" -H "Content-Type: application/json" \\
-d '{"payload": [{"attribute_key": "cpf", "filter_operator": "equal_to", "values": [12345678901], "attribute_model": "custom_attribute"}]}'
→ {"status":500,"error":"Internal Server Error"}
- Same request with the value quoted as a string:
... -d '{"payload": [{"attribute_key": "cpf", "filter_operator": "equal_to", "values": ["12345678901"], "attribute_model": "custom_attribute"}]}'
→ HTTP 200 with the correct result.
Expected behavior
Either coerce numeric values to strings for text attributes (or reject with a 400 and a clear message) — and the dashboard should show an error state instead of silently keeping the stale, unfiltered list under an applied filter chip.
Environment
- Self-hosted Chatwoot v4.16.2 (Docker image), PostgreSQL on RDS
- Reproducible 100% of the time via plain API calls (no proxy/WAF in between)
Additional context
Likely the custom-attribute branch of the filter query builder calling a String method on an Integer. Possibly related: contains on the same text custom attribute times out on large contact tables (unindexed JSONB scan), but that is a separate performance concern — this report is about the 500 + silent UI failure.
Describe the bug
POST /api/v1/accounts/{id}/contacts/filterreturns HTTP 500 when filtering a text-type custom attribute with a JSON numeric value. The same filter with the value as a JSON string works correctly.This bites hardest through the dashboard: when an agent types a digits-only value (e.g. a national ID stored as a text custom attribute) into the contacts filter, the request can fail — and the UI does not surface the error. It keeps showing the previous unfiltered contact list with the filter chip applied, which reads as "these contacts matched", so agents trust a wrong result.
To Reproduce
text(e.g. keycpf).→
{"status":500,"error":"Internal Server Error"}... -d '{"payload": [{"attribute_key": "cpf", "filter_operator": "equal_to", "values": ["12345678901"], "attribute_model": "custom_attribute"}]}'→ HTTP 200 with the correct result.
Expected behavior
Either coerce numeric values to strings for text attributes (or reject with a 400 and a clear message) — and the dashboard should show an error state instead of silently keeping the stale, unfiltered list under an applied filter chip.
Environment
Additional context
Likely the custom-attribute branch of the filter query builder calling a String method on an Integer. Possibly related:
containson the same text custom attribute times out on large contact tables (unindexed JSONB scan), but that is a separate performance concern — this report is about the 500 + silent UI failure.