nautechsystems/nautilus_trader · error
Payload intent ID {} is not positive
Error message
Payload intent ID {} is not positive What it means
validate_context requires a positive (non-zero) intent_id in the PayloadContext. Zero is treated as an unset/placeholder intent id, which would let a sealed payload reference nothing meaningful, so seal/unseal reject it.
Source
Thrown at crates/adapters/blockchain/src/execution/sealing.rs:435
let key_id = envelope[1..1 + KEY_ID_LEN]
.try_into()
.expect("fixed key ID slice length");
let nonce_start = 1 + KEY_ID_LEN;
let ciphertext_start = nonce_start + NONCE_LEN;
Ok(ParsedEnvelope {
key_id,
nonce: &envelope[nonce_start..ciphertext_start],
ciphertext_and_tag: &envelope[ciphertext_start..],
})
}
fn validate_context(context: &PayloadContext, deployment_id: &str) -> anyhow::Result<()> {
anyhow::ensure!(
context.deployment_id == deployment_id,
"Payload deployment ID does not match the configured key set"
);
anyhow::ensure!(
context.intent_id > 0,
"Payload intent ID {} is not positive",
context.intent_id
);
Ok(())
}
fn encode_aad(key_id: &[u8; KEY_ID_LEN], context: &PayloadContext) -> anyhow::Result<Vec<u8>> {
let mut aad = Vec::with_capacity(
AAD_DOMAIN.len()
+ context.deployment_id.len()
+ 20
+ 32
+ KEY_ID_LEN
+ 9 * size_of::<u32>(),
);
append_aad_field(&mut aad, AAD_DOMAIN)?;
append_aad_field(&mut aad, &[ENVELOPE_VERSION])?;View on GitHub (pinned to 18893faf8b)
Solutions
- Populate intent_id from the actual intent record before constructing PayloadContext
- Add a check/validation at the source (DB read or API response) that intent_id > 0
- Find where the zero default came from — likely an unfilled struct field — and make intent_id construction explicit
Example fix
// before
let ctx = PayloadContext { deployment_id: dep.to_string(), intent_id: 0, .. };
seal(&ctx, ...)?;
// after
let ctx = PayloadContext { deployment_id: dep.to_string(), intent_id: intent.id, .. };
anyhow::ensure!(ctx.intent_id > 0, "intent_id must be positive");
seal(&ctx, ...)?; Defensive patterns
Strategy: validation
Validate before calling
fn ensure_positive_intent_id(context: &PayloadContext) -> anyhow::Result<()> {
anyhow::ensure!(context.intent_id > 0, "intent_id must be > 0, got {}", context.intent_id);
Ok(())
} Type guard
fn has_valid_intent_id(context: &PayloadContext) -> bool {
context.intent_id > 0
} Try / catch
match seal(&context, payload, deployment_id) {
Ok(sealed) => sealed,
Err(e) if e.to_string().contains("not positive") => {
// load the real intent record before retrying
}
Err(e) => return Err(e),
} Prevention
- Construct PayloadContext from a fetched intent record, never from defaults
- Validate intent_id at the persistence boundary where the intent is loaded
- Use a newtype/Option so an unset intent id cannot silently be 0
When it happens
Trigger: Calling seal() or unseal() with a PayloadContext constructed with intent_id: 0 — typically a default-initialized struct or an intent id field that was never populated from the database record.
Common situations: PayloadContext built with Default::default() and only some fields filled; a DB row where intent_id was NULL/default; deserialization of a context from a source that omitted the intent id.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Invalid venue {}, expected Blockchain DEX format
- `router_addresses` must contain at least one router address
- Quote spend limit for {token_in} -> {token_out} is denominat
- Pool identifier {pool_identifier} is a pool ID; only address
- {context} verification is locally invalid
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/8df21280cefe6531.
Report an issue: GitHub.