Found on main @ a258137, verified by execution against live Postgres 17.
updateMany(table, conditions, data) appends a WHERE only when conditions is an array, or an object that both lacks a raw key and has at least one key (client.ts ~:7882-7900). Anything else produces an UPDATE with no predicate.
Repro
// table has 4 rows
await db.updateMany('t', raw('id = 1'), { name: 'T' }) // -> 1:T 2:T 3:T 4:T
await db.updateMany('t', {}, { name: 'T' }) // -> 1:T 2:T 3:T 4:TBoth rewrite the whole table, silently, with no error.
The fragment form is the dangerous one: raw is a public export and a fragment is the natural way to express a condition updateMany cannot otherwise take, so this reads like the intended usage.
The empty-object form matters because conditions is frequently built up from user input — updateMany(t, buildFilter(req.query), data) rewrites every row the moment the filter comes back empty.
Suggested fix
Same shape as #1101: render a fragment as a predicate (it is a supported input elsewhere), and refuse a condition set that produces no WHERE rather than proceeding without one. Callers wanting an unfiltered update can say so by not passing conditions.
Found by an automated sweep; reproduced by me before filing.