vectordotdev/vector · error

shutdown_force_trigger for source

Error message

shutdown_force_trigger for source "{id}" not found in the ShutdownCoordinator

What it means

Panic from `.expect("all required builder parameters specified")` in `delete_messages` (src/sources/aws_sqs/source.rs:207), on the aws-sdk-sqs `DeleteMessageBatchRequestEntry` builder. The builder's `build()` errs only when required setters (`id`, `receipt_handle`) are missing; here `id` is the loop index stringified and the receipt comes from the caller, so a failure means a None/empty receipt slipped through or an SDK change added required fields.

Solutions

  1. Filter out empty receipts before calling `delete_messages` (`receipts.retain(|r| !r.is_empty())`).
  2. Confirm `.id(id.to_string())` and `.receipt_handle(receipt)` are both chained before `.build()`.
  3. Pin the aws-sdk-sqs version expected by vector and review its builder's required fields after upgrades.
  4. Replace the expect with error handling that emits `SqsMessageDeleteError` and skips the entry.

Example fix

// before
batch = batch.entries(
    DeleteMessageBatchRequestEntry::builder()
        .id(id.to_string())
        .receipt_handle(receipt)
        .build()
        .expect("all required builder parameters specified"),
);
// after
let receipts: Vec<_> = receipts.into_iter().filter(|r| !r.is_empty()).collect();
// and on build failure:
.unwrap_or_else(|e| panic!("SQS delete entry invalid: {e}"))
Defensive patterns

Strategy: validation

Validate before calling

receipts.retain(|r| !r.is_empty());
// then build with .ok() and skip failures

Type guard

fn non_empty(r: &str) -> Option<&str> { (!r.is_empty()).then_some(r) }

Try / catch

match DeleteMessageBatchRequestEntry::builder().id(id.to_string()).receipt_handle(receipt).build() {
    Ok(entry) => batch = batch.entries(entry),
    Err(e) => emit!(SqsMessageDeleteError { error: &e.into() }),
}

Prevention

When it happens

Trigger: Calling `delete_messages` with a receipts vector containing values, then building entries — fires if `receipt_handle` is empty/None coerced, or if an aws-sdk-sqs upgrade makes additional fields required on `DeleteMessageBatchRequestEntry`.

Common situations: aws-sdk-sqs version mismatch after a dependency bump; callers passing empty-string receipts collected from partially-processed messages; refactor renaming fields so a setter chain silently drops `.receipt_handle()`.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16). Data as JSON: /api/errors/870e88f1d223d03e. Report an issue: GitHub.

Appendix: source

Thrown at lib/vector-common/src/shutdown.rs:280

    ) -> impl Future<Output = bool> + use<> {
        let (_, begin_shutdown_trigger) = self.begun_triggers.remove(id).unwrap_or_else(|| {
            panic!(
                "shutdown_begun_trigger for source \"{id}\" not found in the ShutdownCoordinator"
            )
        });
        // This is what actually triggers the source to begin shutting down.
        begin_shutdown_trigger.cancel();

        let shutdown_complete_tripwire = self
            .complete_tripwires
            .remove(id)
            .unwrap_or_else(|| {
                panic!(
                "shutdown_complete_tripwire for source \"{id}\" not found in the ShutdownCoordinator"
            )
            });
        let shutdown_force_trigger = self.force_triggers.remove(id).unwrap_or_else(|| {
            panic!(
                "shutdown_force_trigger for source \"{id}\" not found in the ShutdownCoordinator"
            )
        });
        SourceShutdownCoordinator::shutdown_source_complete(
            shutdown_complete_tripwire,
            shutdown_force_trigger,
            id.clone(),
            Some(deadline),
        )
    }

    /// Returned future will finish once all *current* sources have finished.
    #[must_use]
    pub fn shutdown_tripwire(&self) -> future::BoxFuture<'static, ()> {
        let futures = self
            .complete_tripwires
            .values()
            .cloned()

View on GitHub (pinned to bdb87aeaa4)