Cybern3rdC
Convex Community5w ago
4 replies
Cybern3rd

WebSocket returns data that doesn't exist in database (CLI works fine)

🪲Bug Report
1. Full-scope summary
Problem: The frontend gets prayer data over the Convex WebSocket that does not exist in the database (and sometimes the returned document _id is from another table, e.g. notificationSettings). The same Convex deployment returns correct data when queried via the CLI (e.g. empty array when no prayer exists). So we have a WebSocket vs CLI data mismatch for the same deployment and same logical query.

Key details:

Code: A mutation queries prayers by language and date and returns the first result (or null). Via WebSocket it returns a document; via CLI it returns []/null when no prayer exists.
Schema: Table prayers with index by_language_and_date on language and date. The phantom document’s _id is from table notificationSettings, not prayers.
Observed: Same wrong result with queries, actions, and mutations over WebSocket; different browsers/devices; cache cleared; redeployed. CLI is always correct.

2. Version & environment
Detail Value
Convex version 1.31.5
Convex client version 1.31.5 (convex npm package)
Programming language TypeScript
Runtime (with version) Node v24.13.0
(Framework: Next.js 16.1.3, React 19.2.3)

3. Reproducible scenario (bug)
Steps:

CLI – correct behaviour
Run:
npx convex run "prayers:debugListAllPrayers" '{"date": "2026-02-01", "language": "en"}'
Result: [] (no prayer exists for that date/language).

WebSocket – wrong behaviour
In the app, open the page that calls getPrayerViaMutation with the same date and language.
Result: Frontend receives a prayer object (e.g. title "In the Stillness of Winter's Heart") with an _id and full JSON, as if a prayer existed.

Proof the WebSocket data is wrong
Use the returned _id in a delete (or any) operation that expects a prayers document.
Result: ArgumentValidationError: Found ID "..." from table \notificationSettings
, which does not match the table name in validator 
⁩v.id("prayers")
. So the WebSocket is returning a document from another table, not fromprayers
.

Minimal code (mutation that shows the mismatch):

export const getPrayerViaMutation = mutation({
args: {
language: v.union(v.literal("en"), v.literal("es"), v.literal("fr"), v.literal("pt")),
date: v.string(),
},
handler: async (ctx, args) => {
const prayer = await ctx.db
.query("prayers")
.withIndex("by_language_and_date", (q) =>
q.eq("language", args.language).eq("date", args.date)
)
.order("desc")
.first();
return prayer;
},
});
Same mutation: correct result via CLI, wrong (phantom/cross-table) result via WebSocket.

4. Network test
(Ran against my DEV deployment; same Convex infrastructure. All checks passed.)

- Performing network test...
✔ Deployment URL: [REDACTED - per forum guidelines]
✔ OK: DNS lookup => 52.44.230.118:ipv4 (86.96ms)
✔ OK: TCP connect (24.51ms)
✔ OK: TCP connect (21.98ms)
✔ OK: HTTP check (35.73ms)
✔ OK: HTTPS check (60.43ms)
✔ OK: WebSocket connection established.
✔ OK: echo 128 B (16.98ms, 7.4 KB/s)
✔ OK: echo 4.0 MB (711.45ms, 5.6 MB/s)
✔ Network test passed.

5. What I’d like
WebSocket responses should match CLI for the same deployment and same function: return the actual document from the database or null when none exists, and never return a document from a different table.

Account verified – you can check my deployment logs if needed.

Thanks in advance for your help!
Was this page helpful?