nautechsystems/nautilus_trader · error · anyhow::Error
`synthetic` {synthetic.id} does not exist
Error message
`synthetic` {synthetic.id} does not exist What it means
`DataActor::update_synthetic` requires the synthetic to already exist in the cache; it performs an update by re-adding. If no instrument with that `synthetic.id` is cached, updating is meaningless and the call bails.
Source
Thrown at crates/common/src/actor/data_actor.rs:4326
if cache.borrow().synthetic(&synthetic.id).is_some() {
anyhow::bail!("`synthetic` {} already exists", synthetic.id);
}
cache.borrow_mut().add_synthetic(synthetic)
}
/// Updates the `synthetic` instrument in the cache, replacing the existing entry.
///
/// # Errors
///
/// Returns an error if no synthetic with the same ID already exists, or if the
/// backing cache fails to persist the replacement. Panics if the actor is not
/// registered with a trader. // panics-doc-ok
pub fn update_synthetic(&self, synthetic: SyntheticInstrument) -> anyhow::Result<()> {
self.check_registered();
let cache = self.cache_rc();
if cache.borrow().synthetic(&synthetic.id).is_none() {
anyhow::bail!("`synthetic` {} does not exist", synthetic.id);
}
cache.borrow_mut().add_synthetic(synthetic)
}
/// Subscribes the actor to data.
///
/// # Panics
///
/// Panics if the actor is not properly registered.
pub fn subscribe_data(
&mut self,
handler: ShareableMessageHandler,
data_type: DataType,
client_id: Option<ClientId>,
params: Option<Params>,
) {
assert!(
self.is_properly_registered(),View on GitHub (pinned to 18893faf8b)
Solutions
- Add the synthetic first with `add_synthetic`, then update
- Verify the synthetic ID matches the one previously added
- Ensure the same cache database is in use as when the synthetic was added
Example fix
// before
actor.update_synthetic(spread)?; // may bail if never added
// after
if actor.cache_rc().borrow().synthetic(&spread.id).is_some() {
actor.update_synthetic(spread)?;
} else {
actor.add_synthetic(spread)?;
} Defensive patterns
Strategy: validation
Validate before calling
if cache.borrow().synthetic(&id).is_none() {
actor.add_synthetic(synthetic)?; // add instead of update
} else {
actor.update_synthetic(synthetic)?;
} Try / catch
if let Err(e) = actor.update_synthetic(synthetic.clone()) {
if e.to_string().contains("does not exist") {
actor.add_synthetic(synthetic)?;
} else { return Err(e); }
} Prevention
- Only update synthetics that were previously added
- Verify IDs match those used at add time
- Use add-then-update flows in fresh cache environments
When it happens
Trigger: Calling `actor.update_synthetic(synthetic)` when `cache.synthetic(&synthetic.id)` is None — the synthetic was never added, was created with a typo'd ID, or was removed earlier.
Common situations: Typo in the synthetic ID; updating in a fresh process/cache where the synthetic was never registered; config change renamed the ID so the update targets a nonexistent key.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- Pool {pool_identifier} is not registered
- `synthetic` {synthetic.id} already exists
- Cannot update position {}: not found in cache
- Cannot update position {position_id}: not found in cache
- Instrument {instrument_id} not found in cache
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/5d182c2be73d3a89.
Report an issue: GitHub.