risingwavelabs/risingwave · error · DmlError

table reader closed

Error message

table reader closed

What it means

DmlError::ReaderClosed indicates the table reader associated with a DML operation has been closed — the channel from the streaming executors to the DML path was dropped, typically because the streaming actor backing the table was stopped, restarted, or the table was dropped.

Solutions

  1. Re-establish the write path: recreate the DML session/statement so a fresh table reader is acquired.
  2. Verify the target table still exists and the streaming actors are running.
  3. Treat it as transient during restarts and retry with backoff after the cluster is healthy.
Defensive patterns

Strategy: try-catch

Validate before calling

// verify table exists and cluster is up before reusing a long-lived DML reader

Try / catch

try { writeThroughReader(reader); }
catch (e) {
  if (String(e).includes("table reader closed")) { reader = await reopenReader(tableId); writeThroughReader(reader); }
  else throw e;
}

Prevention

When it happens

Trigger: A write is issued through a table reader whose streaming executor has terminated (actor restart, table drop, cluster shutdown) — the read channel is closed and further DML through it fails.

Common situations: Ingestion client holding a long-lived reader while the MV/table is dropped elsewhere; worker restarts under the client; shutting down the cluster while writes are still being submitted.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/530b634e572348dd. Report an issue: GitHub.

Appendix: source

Thrown at src/dml/src/error.rs:26

//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/// The error type for DML operations.
#[derive(thiserror::Error, Debug)]
pub enum DmlError {
    #[error("table schema has changed, please try again later")]
    SchemaChanged,

    #[error(
        "DML is not permitted during cluster recovery (no available table reader in streaming executors)"
    )]
    NoReader,

    #[error("table reader closed")]
    ReaderClosed,
}

pub type Result<T> = std::result::Result<T, DmlError>;

View on GitHub (pinned to 6469eb736d)