{"record":{"id":"8df21280cefe6531","repo":"nautechsystems/nautilus_trader","slug":"payload-intent-id-is-not-positive","errorCode":null,"errorMessage":"Payload intent ID {} is not positive","messagePattern":"Payload intent ID (.+?) is not positive","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/sealing.rs","lineNumber":435,"sourceCode":"\n    let key_id = envelope[1..1 + KEY_ID_LEN]\n        .try_into()\n        .expect(\"fixed key ID slice length\");\n    let nonce_start = 1 + KEY_ID_LEN;\n    let ciphertext_start = nonce_start + NONCE_LEN;\n    Ok(ParsedEnvelope {\n        key_id,\n        nonce: &envelope[nonce_start..ciphertext_start],\n        ciphertext_and_tag: &envelope[ciphertext_start..],\n    })\n}\n\nfn validate_context(context: &PayloadContext, deployment_id: &str) -> anyhow::Result<()> {\n    anyhow::ensure!(\n        context.deployment_id == deployment_id,\n        \"Payload deployment ID does not match the configured key set\"\n    );\n    anyhow::ensure!(\n        context.intent_id > 0,\n        \"Payload intent ID {} is not positive\",\n        context.intent_id\n    );\n    Ok(())\n}\n\nfn encode_aad(key_id: &[u8; KEY_ID_LEN], context: &PayloadContext) -> anyhow::Result<Vec<u8>> {\n    let mut aad = Vec::with_capacity(\n        AAD_DOMAIN.len()\n            + context.deployment_id.len()\n            + 20\n            + 32\n            + KEY_ID_LEN\n            + 9 * size_of::<u32>(),\n    );\n    append_aad_field(&mut aad, AAD_DOMAIN)?;\n    append_aad_field(&mut aad, &[ENVELOPE_VERSION])?;","sourceCodeStart":417,"sourceCodeEnd":453,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/execution/sealing.rs#L417-L453","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nlet ctx = PayloadContext { deployment_id: dep.to_string(), intent_id: 0, .. };\nseal(&ctx, ...)?;\n// after\nlet ctx = PayloadContext { deployment_id: dep.to_string(), intent_id: intent.id, .. };\nanyhow::ensure!(ctx.intent_id > 0, \"intent_id must be positive\");\nseal(&ctx, ...)?;","handlingStrategy":"validation","validationCode":"fn ensure_positive_intent_id(context: &PayloadContext) -> anyhow::Result<()> {\n    anyhow::ensure!(context.intent_id > 0, \"intent_id must be > 0, got {}\", context.intent_id);\n    Ok(())\n}","typeGuard":"fn has_valid_intent_id(context: &PayloadContext) -> bool {\n    context.intent_id > 0\n}","tryCatchPattern":"match seal(&context, payload, deployment_id) {\n    Ok(sealed) => sealed,\n    Err(e) if e.to_string().contains(\"not positive\") => {\n        // load the real intent record before retrying\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["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"],"tags":["blockchain","validation","domain-logic"],"backgroundTag":"value-out-of-range","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}