Custom entity view empty for non-admin users despite API returning data correctly

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • assoclip
    Junior Member
    • Apr 2026
    • 1

    #1

    Custom entity view empty for non-admin users despite API returning data correctly

    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:
    • 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
    What does not work
    • 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)
    Key discovery — freshly created entity works, migrated entity does not


    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
    1. Install EspoCRM v9.3.4
    2. Create a custom Person entity in v5.7, export its configuration and data
    3. Import the entity configuration and data into v9.3.4
    4. Create a non-admin user with read: all on this entity
    5. 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.
Working...