Skip to content

fix(payload): actionable error from cloudsync_payload_chunks when uninitialized#54

Open
andinux wants to merge 2 commits into
mainfrom
fix/payload-chunks-uninitialized-error
Open

fix(payload): actionable error from cloudsync_payload_chunks when uninitialized#54
andinux wants to merge 2 commits into
mainfrom
fix/payload-chunks-uninitialized-error

Conversation

@andinux

@andinux andinux commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Problem

When the /check endpoint queries cloudsync_payload_chunks on a database that is initialized for cloudsync locally but not configured on the cloud node, the server receives a misleading error:

Database query failed: SQL logic error

while cloudsync_payload_apply in the same scenario already returns the actionable message:

cloudsync is not initialized: call SELECT cloudsync_init('<table_name>') to enable sync on a table before calling cloudsync_payload_apply().

Root cause

cloudsync_payload_chunks is a virtual table whose xFilter runs internal statements over the eponymous cloudsync_changes vtab. On an unconfigured database those statements prepare fine but fail at step time, and the error code propagated out of xFilter without ever setting the outer vtab's zErrMsg, so SQLite surfaced the generic "SQL logic error". The watermark MAX(db_version) query even discarded its step error entirely, silently scanning an empty window.

Fix

  • payload_chunks_filter now starts with the same cloudsync_context_is_initialized guard used by cloudsync_payload_apply and raises: "cloudsync is not initialized: call SELECT cloudsync_init('<table_name>') to enable sync on a table before querying cloudsync_payload_chunks."
  • payload_chunks_step_source copies the inner statement's error message onto the vtab's zErrMsg, so any other inner error (e.g. "cloudsync has no tables configured") reaches the caller instead of being masked.
  • A watermark-query step failure is propagated as an error instead of being ignored.

No PostgreSQL changes: the PG SRF errors through ereport/SPI with its own messages, and the extension version stays at 1.1 (patch bump only), so no migration script is needed.

Tests

  • New unit test Payload Chunks Uninitialized: runs the /check-style query on a database without cloudsync_init and asserts the actionable message. All 148 SQLite unit tests pass; PostgreSQL full suite passes with 0 failures.
  • The e2e Failure Path Test now asserts the forwarded "cloudsync is not initialized" message on all three surfaces (send lastFailure JSON, the non-retryable SQL error raised by receive_changes, and the sync JSON) instead of only checking that a lastFailure object exists. Note: this test stays red against server nodes still running the 1.1.0 extension (they forward the old "SQL logic error" text) and goes green once the node runs 1.1.1.
  • Verified manually: a fresh connection to an already-configured database is not falsely rejected (extension load-time init prepares the probe statement), and the exact reported /check query on an uninitialized db now returns the actionable message.

An independent review pass approved the change; noted follow-up (not in scope): on PostgreSQL, cloudsync_payload_chunks on an unconfigured node silently returns zero chunks rather than erroring — parity there is a separate product decision.

Versioning

  • CLOUDSYNC_VERSION bumped to 1.1.1 (bug shipped in released 1.1.0)
  • CHANGELOG entry added under ## [1.1.1] - 2026-07-10

🤖 Generated with Claude Code

andinux and others added 2 commits July 10, 2026 16:47
…nitialized

Querying the cloudsync_payload_chunks vtab on a database where cloudsync
was never initialized surfaced a bare "SQL logic error": the internal
statements over cloudsync_changes failed at step time and the error code
propagated out of xFilter without ever setting the outer vtab's zErrMsg.
The /check endpoint hit this on nodes not configured for cloudsync.

Guard xFilter with the same is-initialized check (and message) used by
cloudsync_payload_apply, propagate inner-statement messages onto the
vtab, and stop ignoring watermark MAX() step failures.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…re path

The Failure Path Test only checked that a lastFailure object existed. Now
that cloudsync_payload_chunks propagates its error, the server forwards
"cloudsync is not initialized" for the check job too (previously a bare
"SQL logic error"), so assert the message on all three surfaces: the
send lastFailure JSON, the non-retryable SQL error raised by
receive_changes, and the sync JSON. Goes green once the node runs 1.1.1.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant