Conversation
| { errors: Object.fromEntries(errors) } | ||
| ); | ||
| // Not enough responses — throw collected node errors for caller to aggregate | ||
| throw nodeErrors; |
There was a problem hiding this comment.
Empty nodeErrors array causes misleading error on epoch disagreement
Medium Severity
When all WebSocket connections succeed but no single epoch reaches the threshold (e.g., 3 services each returning a different epoch with threshold 2), nodeErrors is empty and throw nodeErrors throws []. In distributedOprf, [].every(isNodeError) is vacuously true, so aggregateError(threshold, []) is called with an empty array. This falls through all aggregation checks and returns a NodeErrorDisagreement with the message "Nodes returned disagreeing errors" and an empty nodeErrors detail — even though no nodes actually errored. The real cause (epoch disagreement) is completely lost.
Additional Locations (1)
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
| } catch (err) { | ||
| // initSessions throws NodeError[] on threshold failure | ||
| if (Array.isArray(err) && err.every(isNodeError)) { | ||
| throw aggregateError(threshold, err as NodeError[]); |
There was a problem hiding this comment.
Empty error array causes misleading aggregation result
Medium Severity
When all WebSocket connections succeed but no epoch bucket reaches threshold (e.g., all nodes are on different epochs), initSessions throws an empty NodeError[]. In distributedOprf, the guard err.every(isNodeError) is vacuously true for empty arrays, so aggregateError(threshold, []) is called. This produces a misleading NodeErrorDisagreement with zero nodeErrors and the message "Nodes returned disagreeing errors" — when the real issue is epoch disagreement, not node errors.


Note
Medium Risk
Medium risk because it changes public API signatures (
distributedOprf/initSessions) and overhauls error propagation/handling paths across WebSocket and session management.Overview
Refactors
@taceo/oprf-clientto take pre-built WebSocket service URLs instead of{baseUrl,module,protocolVersion}parameters, addingtoOprfUrito construct endpoints and updating the example CLI + README usage accordingly.Introduces a two-tier error model (
NodeError/ServiceErrorvsOprfClientError) and newaggregateError(threshold, errors)logic, withinitSessionsnow throwingNodeError[]on threshold failure anddistributedOprftranslating those into protocol-level errors (plus a dedicatedCannotFinishSessionwrapper). Tests are updated to cover the new URI builder and error aggregation behavior.Written by Cursor Bugbot for commit 881eb9e. This will update automatically on new commits. Configure here.