nautechsystems/nautilus_trader · error

Invalid `key`, missing a '{REDIS_DELIMITER}' delimiter, was

Error message

Invalid `key`, missing a '{REDIS_DELIMITER}' delimiter, was {key}

What it means

When draining the write buffer, each Redis key must be of the form '<collection><delimiter><suffix>' so the cache can determine which collection (orders, positions, etc.) it belongs to. get_collection_key splits on the REDIS_DELIMITER (colon) and raises this error when a key contains no delimiter. It indicates a malformed or foreign key entered the cache buffer.

Source

Thrown at crates/infrastructure/src/redis/cache.rs:1218

    if config.use_trader_prefix {
        key.push_str("trader-");
    }

    key.push_str(trader_id.as_str());

    if config.use_instance_id {
        key.push(REDIS_DELIMITER);
        write!(key, "{instance_id}").expect("writing to String cannot fail");
    }

    key
}

fn get_collection_key(key: &str) -> anyhow::Result<&str> {
    key.split_once(REDIS_DELIMITER)
        .map(|(collection, _)| collection)
        .ok_or_else(|| {
            anyhow::anyhow!("Invalid `key`, missing a '{REDIS_DELIMITER}' delimiter, was {key}")
        })
}

#[derive(Debug)]
pub struct RedisCacheDatabaseAdapter {
    pub database: RedisCacheDatabase,
}

impl RedisCacheDatabaseAdapter {
    fn encoding(&self) -> SerializationEncoding {
        self.database.get_encoding()
    }

    fn send_command(
        &self,
        op_type: DatabaseOperation,
        key: String,
        payload: Option<Vec<Bytes>>,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Log/inspect the offending key and rewrite it using the standard '<COLLECTION>{REDIS_DELIMITER}...' format.
  2. Check any custom writers to the cache buffer and ensure keys use the same delimiter convention as the built-in adapters.
  3. If keys come from an older schema or migration, transform them to the current format before draining.
  4. Upgrade nautilus_trader if the delimiter constant changed between versions and old keys no longer match.

Example fix

// before
buffer.push("mykey123", payload);
// after
buffer.push(format!("{ORDERS}{REDIS_DELIMITER}mykey123"), payload);
Defensive patterns

Strategy: validation

Validate before calling

fn key_is_valid(key: &str, delim: char) -> bool { key.contains(delim) && !key.starts_with(delim) }

Type guard

fn is_collection_key(key: &str) -> bool { key.split_once(':').is_some() }

Prevention

When it happens

Trigger: drain_buffer processes a buffered key that lacks the REDIS_DELIMITER separator — e.g. a key written without the expected '<COLLECTION>:...' prefix format.

Common situations: Custom code or an older/other component writing cache keys in a different format, a corrupted/migrated Redis dataset being drained, or manual key construction that skipped the delimiter convention.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/d30698991cd60d5a. Report an issue: GitHub.