full-address-column icon indicating copy to clipboard operation
full-address-column copied to clipboard

Race condition: `gFolder` is undefined in `addCustomColumn()`

Open Snowball-V opened this issue 5 months ago • 1 comments

🐞 Bug Report: gFolder is undefined in addCustomColumn

❗️Error Message

Uncaught TypeError: gFolder is undefined
    addCustomColumn chrome://messenger/content/about3Pane.js:6512
    observe chrome://messenger/content/about3Pane.js:5323
    addCustomColumn chrome://messenger/content/thread-pane-columns.mjs:513
    add jar:file:///.../[email protected]!/implementation.js:60

🧩 Context

  1. The extension [email protected] tries to add its custom columns.

  2. It calls Thunderbird’s built-in addCustomColumn() function.

  3. This function lives in the file thread-pane-columns.mjs.

  4. That file observes an event that eventually triggers addCustomColumn() inside about3Pane.js.

  5. Then 💥 boom — it crashes on line 6512 of about3Pane.js.

  6. The crashing line is:

    const columnStates = gFolder.msgDatabase.dBFolderInfo.getCharProperty("columnStates");
    

🧪 Hypothesis

It seems gFolder is not yet defined at the moment the extension attempts to inject its custom column. This looks like a race condition — it happens randomly.

Observed frequency: This error occurred 1 in ~8.89 runs (precisely 1 in 8.89465132 times), over 351 startups of Thunderbird 115 ESR on a machine running Windows 8.1 + Intel Core i7-4710HQ.

🧾 Excerpt of about3Pane.js (Thunderbird 115 ESR)

The following snippet shows where the error occurs — line 6512 marked with █★█:

/**
 * Adds a custom column to the thread pane.
 *
 * @param {string} columnID - unique ID of the custom column
 */
addCustomColumn(columnID) {
    const column = ThreadPaneColumns.getColumn(columnID);
    if (this.rowTemplate) {
        this.rowTemplate.content.appendChild(this.makeCustomColumnCell(column));
    }
    this.columns.push(column);
    const columnStates = gFolder.msgDatabase.dBFolderInfo.getCharProperty("columnStates"); // █★█
    if (columnStates) {
        this.applyPersistedColumnsState(JSON.parse(columnStates));
    }
    gViewWrapper?.dbView.addColumnHandler(column.id, column.handler);
    this.updateColumns();
    this.restoreSortIndicator();
    threadTree.reset();
}

✅ Expected behavior

The extension should be able to add its column without error. If gFolder is not available, the function should wait or fail gracefully.

💡 Suggested direction

Maybe guard the gFolder access with a presence check or delay the column injection until gFolder is guaranteed to be ready.

Snowball-V avatar Jul 25 '25 23:07 Snowball-V

That should be fixed in ESR 128.

lkosson avatar Jul 26 '25 04:07 lkosson