risingwavelabs/risingwave · error · anyhow::Error

exactly one of job_id or fragment_id must be provided

Error message

exactly one of job_id or fragment_id must be provided

What it means

Guard in risectl resume_backfill: exactly one of job_id or fragment_id must be supplied. Passing both, or neither, leaves no unambiguous protobuf Target to build, so the command fails with this error instead of guessing which backfill to resume.

Solutions

  1. Pass exactly one of --job-id or --fragment-id
  2. If both are set in a script, clear the unwanted one to None/omit the flag

Example fix

// before
resume_backfill(ctx, Some(job_id), Some(fragment_id))
// after
resume_backfill(ctx, Some(job_id), None)
Defensive patterns

Strategy: validation

Validate before calling

match (job_id.is_some(), fragment_id.is_some()) {
    (true, false) | (false, true) => {},
    _ => return Err(anyhow!("provide exactly one of job_id or fragment_id")),
}

Prevention

When it happens

Trigger: Calling the resume-backfill command with both job_id and fragment_id set, or with both omitted (None, None).

Common situations: CLI wrapper passing defaults for both flags; scripting that fills both options unconditionally.

Related errors


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

Appendix: source

Thrown at src/ctl/src/cmd_impl/meta/resume_backfill.rs:31

// limitations under the License.

use anyhow::{Result, anyhow};
use risingwave_pb::ddl_service::RisectlResumeBackfillRequest;
use risingwave_pb::ddl_service::risectl_resume_backfill_request::Target;
use risingwave_pb::id::{FragmentId, JobId};

use crate::CtlContext;

pub async fn resume_backfill(
    context: &CtlContext,
    job_id: Option<JobId>,
    fragment_id: Option<FragmentId>,
) -> Result<()> {
    let target = match (job_id, fragment_id) {
        (Some(job_id), None) => Target::JobId(job_id),
        (None, Some(fragment_id)) => Target::FragmentId(fragment_id),
        _ => {
            return Err(anyhow!(
                "exactly one of job_id or fragment_id must be provided"
            ));
        }
    };

    let meta_client = context.meta_client().await?;
    meta_client
        .risectl_resume_backfill(RisectlResumeBackfillRequest {
            target: Some(target),
        })
        .await?;
    println!("Done.");
    Ok(())
}

View on GitHub (pinned to 6469eb736d)