Problem
The client row cache partitions on getSourcePayloadKey = JSON.stringify(outside_df_params) plus sort state (packages/buckaroo-js-core/src/components/DFViewerParts/SmartRowCache.ts:39-42, gridUtils.ts:430-433). The one field in outside_df_params meant to track server-side data identity — dataframe_id (BuckarooWidgetInfinite.tsx:243-253) — is supplied by no caller in the repo: BuckarooView.tsx:287-299 renders the widget without it, so in server mode it is permanently undefined. The only purge trigger is an outsideDFSig change (DFViewerInfinite.tsx:472-507).
Impact
POST /reload_expr/<session> (and /load_expr reusing a session id with force_reload) replaces the dataflow and resets session state to defaults (server/handlers.py:566-575, 807-808, 849-855). A client sitting at default state recomputes byte-identical outside_df_params: no purge, no remount, and getRequestRows short-circuits from the old partition (SmartRowCache.ts:511-528, 589-596) — the previous expression's rows render under the new summary stats, without a network request. Live for tallyman, which calls /reload_expr on every summary-stat/display-klass hot-reload.
Suggested fix
Carry a per-session load-generation counter on the server, bumped on every /load_expr and /reload_expr, and pass it through as dataframe_id in server mode. One prop closes the hole.
Context
Found while auditing buckaroo 0.15.4 (3313534a) for the cache-soundness bug class behind buckaroo-data/tallyman#163.
Problem
The client row cache partitions on
getSourcePayloadKey=JSON.stringify(outside_df_params)plus sort state (packages/buckaroo-js-core/src/components/DFViewerParts/SmartRowCache.ts:39-42,gridUtils.ts:430-433). The one field inoutside_df_paramsmeant to track server-side data identity —dataframe_id(BuckarooWidgetInfinite.tsx:243-253) — is supplied by no caller in the repo:BuckarooView.tsx:287-299renders the widget without it, so in server mode it is permanentlyundefined. The only purge trigger is anoutsideDFSigchange (DFViewerInfinite.tsx:472-507).Impact
POST /reload_expr/<session>(and/load_exprreusing a session id withforce_reload) replaces the dataflow and resets session state to defaults (server/handlers.py:566-575,807-808,849-855). A client sitting at default state recomputes byte-identicaloutside_df_params: no purge, no remount, andgetRequestRowsshort-circuits from the old partition (SmartRowCache.ts:511-528,589-596) — the previous expression's rows render under the new summary stats, without a network request. Live for tallyman, which calls/reload_expron every summary-stat/display-klass hot-reload.Suggested fix
Carry a per-session load-generation counter on the server, bumped on every
/load_exprand/reload_expr, and pass it through asdataframe_idin server mode. One prop closes the hole.Context
Found while auditing buckaroo 0.15.4 (
3313534a) for the cache-soundness bug class behind buckaroo-data/tallyman#163.