DataTables destroy method leaves stale state after upgrade rollback
0 reputation · 24 May 2026, 17:14 UTC
0 reputation · 24 May 2026, 17:14 UTC
When a DataTable instance is destroyed with the destroy() method, the library removes its internal bookkeeping but leaves the underlying DOM elements, event handlers, and any persisted state untouched. This behavior becomes problematic during a failed upgrade: the new version may initialize over the old table, but the stateSave data stored in localStorage is still present, causing the table to load a stale configuration. Additionally, column visibility settings are not rebuilt, so hidden columns may appear incorrectly after a rollback.
These issues raise uncertainty about how to safely recover from an upgrade that fails to apply correctly. The current API does not provide a built‑in mechanism to clear or reset the stored state when destroy() is called, and the behavior may differ between DataTables 1.10.x and 2.0.x.
stateSave data when a DataTable is destroyed during a failed upgrade?destroy() is invoked?34775 reputation · 24 May 2026, 20:55 UTC
destroy() only tears down the table enhancement — wrapper elements, event handlers, and the internal instance. It deliberately does not delete stateSave data from localStorage, and there is no destroy option that does so. To purge the state you must call table.state.clear() before calling destroy(), or remove the storage key manually if the instance is already gone. Column visibility is not rebuilt by destroy; it is re-applied from the saved state on the next initialization, so clearing the state is what resets it.
When stateSave: true is set, DataTables writes the table's state (page, ordering, search, and columns.visible flags) into web storage under a key that includes the table's id attribute and the page path — typically of the form DataTables_<tableId>_<pathname>. That entry is independent of the table instance. Destroying the table, reloading the page, or rolling back your deployed JavaScript leaves the key untouched. On the next DataTable() call, the saved state is loaded and applied — including column visibility from the other version's column layout, which is exactly the corruption you are seeing after a rollback.
const table = $('#myTable').DataTable();
table.state.clear(); // removes the saved-state entry
table.destroy(); // then tear down the enhancementlocalStorage.clear(), which would wipe unrelated app data:Object.keys(localStorage)
.filter(k => k.startsWith('DataTables_'))
.forEach(k => localStorage.removeItem(k));Embed a schema or app version into the saved state and reject incompatible state on load:
$('#myTable').DataTable({
stateSave: true,
stateSaveParams: (settings, data) => { data.appVersion = '1.10.x'; },
stateLoadParams: (settings, data) => {
if (data.appVersion !== '1.10.x') return false; // discard stale state
}
});Returning false from stateLoadParams causes DataTables to ignore the saved entry, so a rollback to a different version starts clean instead of applying mismatched column-visibility data.
state.clear() exists in both 1.10.x and 2.x, but the storage key format, defaults such as stateDuration (default two hours; stateDuration: 0 switches to sessionStorage), and some API names differ between major versions. Confirm the deployed version with $.fn.dataTable.version and check that version's docs before relying on exact key names. Also note: if your table lacks a stable id, DataTables generates one, making the storage key unpredictable across re-initializations — assign explicit ids.
To verify the fix: open DevTools → Application → Local Storage and confirm the DataTables_* key persists after a bare destroy(), then confirm it disappears after state.clear(). After re-initialization, inspect table.state() to confirm no stale columns.visible entries were applied.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.