fix(activity): use actual bucket IDs in multidevice query (fixes BucketNotFound with aw-sync data) - #969
Conversation
The multidevice query reconstructed bucket IDs as 'aw-watcher-window_<hostname>'/'aw-watcher-afk_<hostname>', but buckets synced from another host via aw-sync carry an '-synced-from-<host>' suffix in their ID while keeping their original hostname field, so on any machine viewing synced data the query failed with BucketNotFound. Fill host_params (an override mechanism that already existed in get_params but was passed as an empty object) with each host's actual bucket IDs, and require both window and afk buckets for a host to be included in the multidevice query, matching the single-device query.
Greptile SummaryThis PR fixes multidevice activity queries for synchronized data by passing each host's actual window and AFK bucket IDs instead of reconstructing IDs from hostnames.
Confidence Score: 4/5The PR appears safe to merge, with only non-blocking test-coverage and type-safety improvements recommended. The new host-specific bucket overrides match the query builder's runtime contract and resolve the synced-ID failure, while the remaining findings concern regression protection and maintainability rather than incorrect runtime behavior. Files Needing Attention: src/stores/activity.ts Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart LR
Inventory[Bucket inventory] --> Filter{Host has window and AFK buckets?}
Filter -- No --> Skip[Exclude host]
Filter -- Yes --> IDs[Select actual bucket IDs]
IDs --> Params[Build host_params by hostname]
Params --> Query[Generate multidevice query]
Query --> Server[Query ActivityWatch]
Server --> Merge[Merge per-host activity]
Reviews (1): Last reviewed commit: "fix(activity): use actual bucket IDs in ..." | Re-trigger Greptile |
| hosts.forEach(host => { | ||
| const bid_window = bucketsStore.bucketsWindow(host)[0]; | ||
| const bid_afk = bucketsStore.bucketsAFK(host)[0]; | ||
| if (bid_window && bid_afk) { | ||
| host_params[host] = { bid_window, bid_afk }; | ||
| hosts_with_buckets.push(host); | ||
| } else { | ||
| console.warn(`Skipping host ${host} in multidevice query: missing window/afk bucket`); | ||
| } | ||
| }); | ||
|
|
||
| const q = queries.multideviceQuery({ | ||
| hosts, | ||
| hosts: hosts_with_buckets, | ||
| filter_afk, | ||
| categories, | ||
| filter_categories, | ||
| host_params: {}, | ||
| host_params: host_params as any, | ||
| always_active_pattern, | ||
| }); |
There was a problem hiding this comment.
Missing multidevice regression tests
The new synced-bucket override path has no focused test covering suffixed bucket IDs or the exclusion of hosts missing an AFK bucket. Because this behavior is enforced during query generation rather than by the type system, a later change could silently restore the original BucketNotFound failure. Please add a multidevice query test that verifies the actual window and AFK bucket IDs are emitted and incomplete hosts are omitted.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
| categories, | ||
| filter_categories, | ||
| host_params: {}, | ||
| host_params: host_params as any, |
There was a problem hiding this comment.
Casting host_params to any suppresses the query builder's declared parameter contract. This means a future incompatible change to either side would not produce a type error. Please model this value using the partial desktop-parameter shape that get_params actually accepts instead of bypassing type checking.
- Extract buildMultideviceHostParams into a pure helper (src/util/multidevice.ts), covered by unit tests including the synced-bucket-ID regression (the query must not reference reconstructed 'aw-watcher-window_<host>' IDs). - Replace the 'as any' cast by typing host_params values as Partial overrides, matching what get_params actually applies.
|
Thanks for the review! Both non-blocking findings are addressed in d5ab9e7:
|
Fix BucketNotFound in multidevice query when viewing aw-sync data
Problem
With
aw-syncset up between machines, enabling the "Use multidevice query" developer setting and opening the Activity view fails on every machine except the one being viewed:Root cause
Buckets pulled in by
aw-synckeep their originalhostnamefield, but their bucket ID gets an-synced-from-<host>suffix (e.g.aw-watcher-window_myhost-synced-from-myhost).bucketsByHostnamegroups by the hostname field, so synced hosts correctly appear in the device list;multideviceQueryreconstructs bucket IDs from the hostname (get_params:bid_window: 'aw-watcher-window_' + host) andquery_multidevice_fullpasseshost_params: {}, so the existing per-host override mechanism inget_paramsis never used;query_bucket("aw-watcher-window_myhost")then fails withBucketNotFound, since only the suffixed ID exists in the local datastore.Fix
host_paramswith each host's actual bucket IDs (first window/afk bucket from the buckets store), so synced buckets are queried by their real IDs.canonicalEventsrequires), matching the single-device path — previously only the window bucket was required, which could produce the same error for the afk bucket.Verification
With two machines synced via aw-sync (one viewing the other's data):
BucketNotFound("Failed to find bucket 'aw-watcher-window_QBZdeMac-mini.local'").union_no_overlap) executes successfully, e.g.{"duration": 22392.738}for the day across both hosts.