nautechsystems/nautilus_trader · warning · anyhow::Error
Execution intent {intent_id} cannot mark {event} emitted
Error message
Execution intent {intent_id} cannot mark {event} emitted What it means
Guard in mark_execution_event_emitted (database.rs:3900-3903): the selected UPDATE affected zero rows. The WHERE clauses make fill and terminal markers mutually exclusive per intent - 'fill' requires NOT terminal_emitted and 'terminal' requires NOT fill_emitted - so re-marking the SAME event twice still matches (rows_affected = 1), and this error fires only when the intent row is absent or the OPPOSING marker is already set. It is a by-design duplicate/ordering suppression, not an infrastructure fault.
Source
Thrown at crates/adapters/blockchain/src/cache/database.rs:3900
) -> anyhow::Result<()> {
let statement = match event {
"acknowledgement" => {
"UPDATE execution_intent SET acknowledgement_emitted = TRUE, updated_at = NOW() WHERE id = $1"
}
"fill" => {
"UPDATE execution_intent SET fill_emitted = TRUE, active = CASE WHEN status = 'finalized' THEN FALSE ELSE active END, updated_at = NOW() WHERE id = $1 AND NOT terminal_emitted"
}
"terminal" => {
"UPDATE execution_intent SET terminal_emitted = TRUE, active = CASE WHEN status IN ('finalized', 'reverted') THEN FALSE ELSE active END, updated_at = NOW() WHERE id = $1 AND NOT fill_emitted"
}
_ => anyhow::bail!("Unknown execution event marker {event}"),
};
let result = sqlx::query(statement)
.bind(intent_id)
.execute(&self.pool)
.await
.map_err(|e| anyhow::anyhow!("Failed to mark execution {event} emitted: {e}"))?;
anyhow::ensure!(
result.rows_affected() == 1,
"Execution intent {intent_id} cannot mark {event} emitted"
);
Ok(())
}
/// Updates the status of a persisted execution transaction record.
///
/// # Errors
///
/// Returns an error if the database operation fails.
pub async fn update_execution_transaction_status(
&self,
chain_id: u32,
transaction_hash: &str,
status: &str,
) -> anyhow::Result<()> {
let result = sqlx::query(View on GitHub (pinned to 2114cf6f76)
Solutions
- Inspect the current markers: SELECT fill_emitted, terminal_emitted, status FROM execution_intent WHERE id = $1
- If the opposing marker is set, treat this as duplicate suppression and skip - the intent already had its single event marker recorded
- Fix dispatcher logic that tries to mark both fill and terminal for one intent; the schema's mutual exclusion is intentional
- If the intent row is absent, verify the intent_id source (it should come from the row that created the event)
Example fix
// before: marking both events for one intent fails on the second call
db.mark_execution_event_emitted(intent_id, "fill").await?;
db.mark_execution_event_emitted(intent_id, "terminal").await?; // Err: cannot mark terminal emitted
// after: choose exactly one marker per intent, and skip if the opposing one is set
let (fill, terminal) = sqlx::query_as::<_, (bool, bool)>(
"SELECT fill_emitted, terminal_emitted FROM execution_intent WHERE id = $1",
).bind(intent_id).fetch_one(&pool).await?;
if !terminal { db.mark_execution_event_emitted(intent_id, "fill").await?; } Defensive patterns
Strategy: validation
Validate before calling
// pre-check: fill and terminal markers are mutually exclusive per intent
let (fill_emitted, terminal_emitted) = sqlx::query_as::<_, (bool, bool)>(
"SELECT fill_emitted, terminal_emitted FROM execution_intent WHERE id = $1",
)
.bind(intent_id)
.fetch_one(&pool)
.await?;
let may_mark = match event {
"fill" => !terminal_emitted,
"terminal" => !fill_emitted,
_ => false,
};
if may_mark {
db.mark_execution_event_emitted(intent_id, event).await?;
} Try / catch
match db.mark_execution_event_emitted(intent_id, event).await {
Ok(()) => Ok(()),
Err(e) if e.to_string().contains("cannot mark") => Ok(()), // duplicate suppression: opposing marker already set
Err(e) => Err(e),
} Prevention
- Emit at most one of fill/terminal per intent; the schema deliberately allows only one marker
- Make dispatch deterministic (single dispatcher per intent) so markers cannot race
- Treat this guard firing as a signal of dispatcher logic bugs, not as a transient fault to retry
- Verify intent_id provenance when it fires with a missing row
When it happens
Trigger: Calling mark_execution_event_emitted(intent_id, "fill") after "terminal" was already marked for that intent (or vice versa); passing an intent_id that does not exist or was archived. The terminal path also only deactivates the intent when status is 'finalized'/'reverted', so wrong-order marking leaves the intent active and this error surfaces.
Common situations: Dispatcher logic that emits both a fill event and a terminal event for the same intent (the schema allows exactly one); replaying recorded events after a restart in a different order than originally dispatched; a stale in-flight dispatch task marking an event after a newer task marked the opposite kind.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Failed to commit execution transition: {e}
- Failed to commit replacement transaction: {e}
- Failed to mark execution {event} emitted: {e}
- Failed to update execution hash {transaction_hash}: {e}
- Execution transaction hash {transaction_hash} was not found
AI-assisted analysis of nautechsystems/nautilus_trader@2114cf6f76 (2026-08-21).
Data as JSON: /api/errors/d286642ca509fa7a.
Report an issue: GitHub.