frappe.get_meta(doctype).has_field("name") returns False for Custom DocTypes, PostgreSQL(Frappe v15)

Hi everyone,

I’m encountering a persistent and critical issue on Frappe v15.67.0 using PostgreSQL (v14.11, via official Docker images). The core problem is that frappe.get_meta("MyCustomDocType").has_field("name") consistently returns False for custom DocTypes defined within my app (nirmaan_stack). This seems to indicate a fundamental issue with metadata loading/representation for the implicit name field.

This issue directly causes:

  1. Inability to filter/search by the name field in frappe.get_list or custom API calls, as checks like meta.has_field("name") fail.
  2. An AttributeError: 'list' object has no attribute 'lower' inside frappe.model.db_query.DatabaseQuery.sanitize_fields when calling frappe.get_list with certain filter structures (like OR conditions for global search), likely because the broken metadata confuses the internal query builder when strict=False.

Environment:

  • Frappe Version: 15.67.0
  • Database: PostgreSQL 14.11 (Debian package 14.11-1.pgdg120+2)
  • Running via Docker using official frappe/frappe-worker and frappe/frappe-nginx images (or similar).
  • Custom Apps: nirmaan_stack (contains the affected DocTypes), nirmaan_crm, frappe_s3_attachment, frappe_types.

DocType Example (“Items” - Simplified for Testing):

We simplified the DocType definition (apps/nirmaan_stack/nirmaan_stack/doctype/items/items.json) to rule out issues with complex fields:

{
    "doctype": "DocType",
    "name": "Items",
    "module": "Nirmaan Stack",
    "engine": "InnoDB", // Note: Engine might be ignored by Postgres adapter
    "naming_rule": "By fieldname",
    "autoname": "item_name",
    "fields": [
        {
            "fieldname": "item_name",
            "fieldtype": "Data",
            "label": "Item Name",
            "reqd": 1,
            // "unique": 1, // Temporarily removed due to data cleanup need
            "in_list_view": 1,
            "in_global_search": 1,
            "search_index": 1
        }
    ],
    "permissions": [
        {
            "role": "System Manager",
            "read": 1, "write": 1, "create": 1, "delete": 1
        }
    ],
    "issingle": 0,
    "sort_field": "modified",
    "sort_order": "DESC"
}

Symptoms & Diagnostics Performed:

  1. Initial Problem: Custom API using frappe.get_list failed with AttributeError: 'list' object has no attribute 'lower' during global search filter construction.
  2. Metadata Investigation: Debug logs revealed meta = frappe.get_meta("Items") resulted in:
    • meta.get_search_fields() returning ['name'] (incorrectly, should include item_name).
    • meta.has_field("name") returning False.
  3. Database Check (psql):
    • SELECT search_fields FROM "tabDocType" WHERE name='Items'; showed search_fields was EMPTY.
    • SELECT ... FROM "tabDocField" WHERE parent='Items'; showed fields like item_name correctly defined with in_global_search = 1.
  4. Standard Fixes Attempted (Failed):
    • bench update --reset (completed successfully after resolving app Git issues).
    • bench --site <site> migrate.
    • bench --site <site> clear-cache.
    • bench --site <site> reload-doctype Items force=True.
    • bench restart.
    • Result: After all these steps, psql still showed tabDocType.search_fields as empty for “Items”, and API logs still showed meta.has_field("name") as False.
  5. Bench Console Test: Manually running the core sync functions:
    frappe.reload_doctype("Items", force=True)
    frappe.db.commit()
    meta = frappe.get_meta("Items")
    frappe.db.updatedb("Items", meta) # Ran without error
    frappe.db.commit()
    frappe.clear_cache(doctype="Items")
    frappe.clear_cache()
    meta = frappe.get_meta("Items")
    print(f"Meta search_fields: {meta.search_fields}") # Output: None
    print(f"Meta has_field('name'): {meta.has_field('name')}") # Output: False
    
    This confirms that even direct calls to reload_doctype and db.updatedb are failing to correctly process/persist the metadata for this DocType regarding search_fields and the implicit name field.
  6. Problem Replicated with Another Custom DocType: The same symptoms (meta.has_field("name") == False, AttributeError in get_list) were observed when testing with another custom DocType (“Procurement Orders”) from the same app. Standard Frappe DocTypes (e.g., “User”, “ToDo”) seem unaffected (meta.has_field("name") is True).

Question:

Has anyone encountered similar issues with custom DocType metadata (specifically search_fields not updating and has_field("name") being false) on Frappe v15.67.0 using PostgreSQL? Is this a known bug, or could there be other environmental factors or deeper conflicts I should investigate? Any pointers on debugging the core get_meta or db.updatedb process for PostgreSQL would be greatly appreciated.

Thanks!