stalwartlabs/stalwart · warning
Sieve test failed: {}
Error message
Sieve test failed: {} What it means
When the `test_mode` feature is enabled, a Sieve script executing the `error` command during message delivery produces RuntimeError::ScriptErrorMessage. Instead of being logged as a runtime event like other errors, this specific variant is treated as an intentional test signal and panics with "Sieve test failed: {err}", so test harnesses can assert delivery behavior. In normal (non-test) builds this variant cannot occur because the code is compiled out.
Source
Thrown at crates/email/src/sieve/ingest.rs:502
arguments,
},
)
.await;
}
Event::CreatedMessage { message, .. } => {
messages.push(SieveMessage {
raw_message: message.into(),
file_into: Vec::new(),
flags: Vec::new(),
did_file_into: false,
});
input = true.into();
}
},
#[cfg(feature = "test_mode")]
Err(sieve::runtime::RuntimeError::ScriptErrorMessage(err)) => {
panic!("Sieve test failed: {}", err);
}
Err(err) => {
trc::event!(
Sieve(SieveEvent::RuntimeError),
Reason = err.to_string(),
SpanId = session_id
);
input = true.into();
}
}
}
// Fail-safe, no discard and no keep seen, assume that something went wrong and file anyway.
if !do_deliver && !do_discard && !do_redirect {
messages[0].file_into.push(INBOX_ID);
}View on GitHub (pinned to e962003857)
Solutions
- If this is a test failure, read the embedded script error text and fix the Sieve script or the test expectation.
- Remove the `error` command from the Sieve script if delivery should succeed.
- Do not build or run production deployments with the test_mode feature; without it, script errors are reported as Sieve RuntimeError events instead.
Example fix
# before (script.sieve) require ["fileinto"]; error; # after require ["fileinto"]; fileinto "INBOX";
Defensive patterns
Strategy: fallback
Validate before calling
// scan deployed Sieve scripts for the error action before enabling delivery: // grep -l '\berror;' ~/.sieve/*.sieve
Try / catch
// in test harnesses, catch the panic to assert the script's error message: let result = std::panic::catch_unwind(|| deliver_message(msg)); assert!(result.is_err(), "expected Sieve error command to abort delivery");
Prevention
- Remove `error;` commands from production Sieve scripts.
- Only build with the test_mode feature in CI/test environments.
- Document that test_mode turns Sieve `error` into a process panic, not a logged event.
When it happens
Trigger: Delivering a message to a Sieve script (sieve_script_ingest, invoked from deliver_message) that executes a Sieve `error` command, while the binary was built with `--features test_mode`. The panic message contains the script's error text.
Common situations: Running the test suite with test scripts that intentionally call `error;` to verify failure paths; enabling test_mode in a development build and pointing a mailbox at a script that still contains an `error` action.
Related errors
- Failed to read {yaml_path:?}
- Node id {node_id} exceeds {MAX_NODE_ID}, panicking to avoid
- Invalid jump position
- unwrap_tls called on non-TLS acceptor
- SieveEvent::RuntimeError
AI-assisted analysis of stalwartlabs/stalwart@e962003857 (2026-09-06).
Data as JSON: /api/errors/9352813b98196307.
Report an issue: GitHub.