Title: Custom Person entity list view empty for non-admin users — .list-container empty despite API returning data correctly
EspoCRM version: 9.3.4
Environment: Shared hosting (O2Switch), PHP 8.4.19, MariaDB 11.4.10
Description
We have a custom entity CClipClipien of type Person, migrated from EspoCRM v5.7.
Non-admin users with read: all permission see an empty list view (.list-container innerHTML = ""), while:
This issue has been investigated exhaustively over several days. We are filing this as a potential bug.
What works
Investigation results
ACL cache — identical for both entities
'CClipClipien' => (object) ['read' => 'all', 'stream' => 'all', 'edit' => 'all', 'delete' => 'no', 'create' => 'yes']
'CLipClipien' => (object) ['read' => 'all', 'stream' => 'all', 'edit' => 'all', 'delete' => 'no', 'create' => 'yes'] ORM metadata cache — identical structure
Both entities: attributes, relations, indexes, collection API response — correct for non-admin user
{"total": 1760, "list": [{"id": "...", "name": "...", "statut": "...", ...}]}
25 records returned correctly with all requested attributes. JavaScript — no errors, routing works
We created CLipClipien (a new Person entity created natively in v9.3.4) with:
Result: CLipClipien works for non-admin users. CClipClipien does not.
The only structural difference found between the two database tables was:
Correcting the column type did not fix the issue. Metadata files — no significant differences found after extensive comparison
Tested modifications (none fixed the issue):
Minimal reproduction
Role configuration (verified)
Comparison table
Question
Is there a known difference in how EspoCRM v9.3 initializes the JavaScript list view for Person entities depending on their origin (migrated vs natively created)?
Specifically: why would .list-container remain empty (no render triggered) for a migrated entity, while the API correctly returns data and no errors are thrown — and an identical freshly-created entity works?
Any pointer to the relevant JavaScript controller, view, or metadata key that controls list view rendering for Person entities would be greatly appreciated.
Thank you.
EspoCRM version: 9.3.4
Environment: Shared hosting (O2Switch), PHP 8.4.19, MariaDB 11.4.10
Description
We have a custom entity CClipClipien of type Person, migrated from EspoCRM v5.7.
Non-admin users with read: all permission see an empty list view (.list-container innerHTML = ""), while:
- The REST API returns data correctly for the same user
- Admin users see all 1760 records
- A freshly created identical Person entity works perfectly
This issue has been investigated exhaustively over several days. We are filing this as a potential bug.
What works
- GET /api/v1/CClipClipien?maxSize=25 returns {"total": 1760, "list": [...]} for non-admin users
- Admin users see all records in the list view
- Non-admin users can create new records in this entity
- Non-admin users can access the detail view of individual records via direct URL
- Non-admin users can see all other custom entities (Base and Person type) correctly
- A freshly created Person entity CLipClipien with identical configuration and same data works correctly for non-admin users
- Non-admin users navigate to #CClipClipien — page title and "+ Create" button appear, but list is empty
- document.querySelector('.list-container').innerHTML → "" (empty string)
- No JavaScript errors in the console
- No server-side errors in the logs
- window.onerror handler catches nothing
- Backbone router correctly matches the CClipClipien route
- Promoting the user to admin fixes the issue immediately; reverting breaks it again
Investigation results
ACL cache — identical for both entities
'CClipClipien' => (object) ['read' => 'all', 'stream' => 'all', 'edit' => 'all', 'delete' => 'no', 'create' => 'yes']
'CLipClipien' => (object) ['read' => 'all', 'stream' => 'all', 'edit' => 'all', 'delete' => 'no', 'create' => 'yes'] ORM metadata cache — identical structure
Both entities: attributes, relations, indexes, collection API response — correct for non-admin user
{"total": 1760, "list": [{"id": "...", "name": "...", "statut": "...", ...}]}
25 records returned correctly with all requested attributes. JavaScript — no errors, routing works
- Backbone.history.fragment = "CClipClipien" ✓
- Route handler matched ✓
- #content > #main > .list-container exists in DOM ✓
- .list-container innerHTML = "" — view never rendered
- No errors caught by window.onerror
- Espo.app is undefined (normal for EspoCRM)
We created CLipClipien (a new Person entity created natively in v9.3.4) with:
- Exact same entityDefs (copy of CClipClipien.json)
- Exact same data (copied via INSERT INTO c_lip_clipien SELECT ... FROM c_clip_clipien)
- Exact same layouts
- Exact same role permissions
Result: CLipClipien works for non-admin users. CClipClipien does not.
The only structural difference found between the two database tables was:
- c_clip_clipien.id was originally varchar(24) (v5.7 legacy) — later corrected to varchar(17)
- c_lip_clipien.id is varchar(17) (v9.3 native)
Correcting the column type did not fix the issue. Metadata files — no significant differences found after extensive comparison
Tested modifications (none fixed the issue):
- Removed aclDefs/CClipClipien.json (had {"contactLink": null, "accountLink": null})
- Simplified clientDefs, scopes, entityDefs, filters.json, list.json
- Set stream: no in all roles via SQL
- Removed entity from all roles except Gestion
- Cleared all server caches (rm -rf data/cache/*, rebuild)
- Tested with multiple browsers (Firefox, Chrome) and incognito mode
Minimal reproduction
- Install EspoCRM v9.3.4
- Create a custom Person entity in v5.7, export its configuration and data
- Import the entity configuration and data into v9.3.4
- Create a non-admin user with read: all on this entity
- Navigate to the entity list as non-admin → list is empty despite API returning data
Role configuration (verified)
- Role "Gestion": CClipClipien → read: all, edit: all, create: yes, delete: no
- Single role, single team — no conflicting permissions
- entity_team table has 0 entries for CClipClipien
- assigned_user_id values verified as valid existing users
Comparison table
| Type | Person | Person |
| Created | Migrated from v5.7 | Fresh in v9.3.4 |
| entityDefs | Identical | Identical |
| Data | Same (copied) | Same (copied) |
| ACL cache | read: all, stream: all | read: all, stream: all |
| API response | Returns 1760 records | Returns 1760 records |
| Non-admin list | Empty | Works |
Question
Is there a known difference in how EspoCRM v9.3 initializes the JavaScript list view for Person entities depending on their origin (migrated vs natively created)?
Specifically: why would .list-container remain empty (no render triggered) for a migrated entity, while the API correctly returns data and no errors are thrown — and an identical freshly-created entity works?
Any pointer to the relevant JavaScript controller, view, or metadata key that controls list view rendering for Person entities would be greatly appreciated.
Thank you.
