risingwavelabs/risingwave · error · anyhow::Error
duplicate worker id {worker_id} in plan, prev {worker_id} ->
Error message
duplicate worker id {worker_id} in plan, prev {worker_id} -> {dup_change} What it means
parse_plan builds a per-worker actor-count diff; inserting a worker id that already appeared in the plan means the plan tries to change the same worker twice, which is ambiguous, so parsing bails with this message.
Source
Thrown at src/ctl/src/cmd_impl/meta/reschedule.rs:170
let captures = regex
.captures(fragment_reschedule_plan)
.ok_or_else(|| anyhow!("plan \"{}\" format illegal", fragment_reschedule_plan))?;
let fragment_id = captures
.get(1)
.and_then(|mat| mat.as_str().parse::<u32>().ok())
.ok_or_else(|| anyhow!("plan \"{}\" does not have a valid fragment id", plan))?;
let worker_changes: Vec<&str> = captures[2].split(',').collect();
let mut worker_actor_diff = HashMap::new();
for worker_change in &worker_changes {
let (worker_id, count) = worker_change.split(':').collect_tuple::<(_, _)>().unwrap();
let worker_id = worker_id.parse().unwrap();
let count = count.parse().unwrap();
if let Some(dup_change) = worker_actor_diff.insert(worker_id, count) {
anyhow::bail!(
"duplicate worker id {worker_id} in plan, prev {worker_id} -> {dup_change}",
);
}
}
if !worker_actor_diff.is_empty() {
reschedules.insert(fragment_id, PbWorkerReschedule { worker_actor_diff });
}
}
Ok(reschedules)
}
pub async fn unregister_workers(
context: &CtlContext,
workers: Vec<String>,
yes: bool,
ignore_not_found: bool,
check_fragment_occupied: bool,View on GitHub (pinned to 6469eb736d)
Solutions
- Deduplicate worker entries so each worker id appears once per plan
- Merge the counts for repeated worker ids into a single entry
- Regenerate the plan from the meta tooling, which produces unique worker ids
Example fix
// before fragment 100 [1:2, 1:5] // after fragment 100 [1:5]
Defensive patterns
Strategy: validation
Validate before calling
let mut seen = HashSet::new();
for w in worker_ids {
if !seen.insert(w) {
return Err(anyhow!("duplicate worker id {}", w));
}
} Prevention
- Deduplicate worker entries before building the plan
- Generate plans with tooling instead of manual merging
When it happens
Trigger: A plan string listing the same worker id in two worker-change entries within (or the parse sees duplicates across) fragment sections, e.g. '1:2,1:5'.
Common situations: Merging plans from multiple runs without deduplicating workers; hand-editing plans and duplicating a worker entry.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- reschedule failed
- Invalid time: {value} {unit} is out of range for a time of d
- Invalid jsonb encoding
- Invalid variant encoding
- should have meta client
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/a9750157f62f6b7d.
Report an issue: GitHub.