stalwartlabs/stalwart · error

Incorrect number of task channels

Error message

Incorrect number of task channels

What it means

The spawned TaskManager IPC worker expects the vector of task channels to convert into a fixed-size array via `try_into()`. This panic fires when the number of channels does not match the expected fixed count (TaskIpc count), which would be an internal bug — the channel vector was built with a different length than the array type expects.

Source

Thrown at crates/services/src/task_manager/manager.rs:296

                                err.id(job.id)
                                    .details("Failed to retrieve task details.")
                                    .caused_by(trc::location!())
                            );
                        }
                    }

                    if refresh_queue || rx.is_empty() {
                        server.notify_task_queue();
                    }
                }
            });
        }
    }

    const REFRESH_INTERVAL: Duration = Duration::from_secs(60);
    tokio::spawn(async move {
        let mut ipc = TaskManagerIpc {
            txs: txs.try_into().expect("Incorrect number of task channels"),
            locked: Default::default(),
            revision: 0,
        };
        let rx = inner.ipc.task_tx.clone();
        loop {
            // Index any queued tasks
            let mut sleep_for = inner.build_server().process_tasks(&mut ipc).await;
            if is_clustered && sleep_for > REFRESH_INTERVAL {
                sleep_for = REFRESH_INTERVAL;
            }

            // Wait for a signal or sleep until the next task is due
            let _ = tokio::time::timeout(sleep_for, rx.notified()).await;
        }
    });
}

pub(crate) trait TaskQueueManager: Sync + Send {

View on GitHub (pinned to e962003857)

Solutions

  1. Update the expected channel count / array type in TaskManagerIpc to match the number of spawned task channels
  2. Check the code that builds `txs` and ensure every task type registers exactly one channel
  3. Add a length assertion when building `txs` to fail fast with a clearer message

Example fix

// before
let ipc = TaskManagerIpc {
    txs: txs.try_into().expect("Incorrect number of task channels"),
// after
assert_eq!(txs.len(), NUM_TASK_TYPES, "task channel count mismatch");
let ipc = TaskManagerIpc {
    txs: txs.try_into().unwrap(),
Defensive patterns

Strategy: validation

Validate before calling

assert_eq!(txs.len(), EXPECTED_TASK_CHANNEL_COUNT, "Incorrect number of task channels");

Type guard

fn is_expected_count(txs: &[Sender<Task>]) -> bool { txs.len() == EXPECTED_TASK_CHANNEL_COUNT }

Try / catch

let Ok(arr) = <[...; N]>::try_into(txs) else {
    panic!("task channel count mismatch: got {}, want {}", txs.len(), N);
};

Prevention

When it happens

Trigger: An internal invariant violation: the number of task senders collected into `txs` differs from the fixed array size expected by TaskManagerIpc, typically after adding/removing a task type in one place but not the other.

Common situations: Developers adding a new task/subsystem to the task manager without updating the fixed channel count; merging partial refactors of the task registry.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.


AI-assisted analysis of stalwartlabs/stalwart@e962003857 (2026-09-06). Data as JSON: /api/errors/acdae31ee346d4f1. Report an issue: GitHub.