nautechsystems/nautilus_trader · error · anyhow::Error

Invalid Hyperliquid outcome symbol '{symbol}': encoding must

Error message

Invalid Hyperliquid outcome symbol '{symbol}': encoding must be numeric

What it means

parse_outcome_symbol_encoding validates the encoding portion of a Hyperliquid outcome symbol (a prediction-market instrument like 'BTC-up-or-down-...' with a numeric encoding). The library throws this because outcome symbol encodings must be plain ASCII digits parseable as u32; a non-numeric encoding cannot be mapped to Hyperliquid's internal outcome index.

Source

Thrown at crates/adapters/hyperliquid/src/common/parse.rs:284

    })
}

fn parse_outcome_symbol_encoding(symbol: &str) -> anyhow::Result<u32> {
    let encoding = symbol
        .strip_prefix('#')
        .or_else(|| symbol.strip_prefix('+'))
        .with_context(|| {
            format!(
                "Invalid Hyperliquid outcome symbol '{symbol}': expected #<encoding> or +<encoding>"
            )
        })?;

    if encoding.is_empty() {
        anyhow::bail!("Invalid Hyperliquid outcome symbol '{symbol}': encoding must not be empty");
    }

    if !encoding.bytes().all(|b| b.is_ascii_digit()) {
        anyhow::bail!("Invalid Hyperliquid outcome symbol '{symbol}': encoding must be numeric");
    }

    encoding
        .parse::<u32>()
        .with_context(|| format!("Invalid Hyperliquid outcome symbol '{symbol}'"))
}

/// Suffix shared by every Nautilus outcome symbol, mirroring `-PERP` / `-SPOT`.
pub const OUTCOME_SYMBOL_SUFFIX: &str = "-OUTCOME";
/// Yes-side label on Nautilus outcome symbols.
pub const OUTCOME_SIDE_YES: &str = "YES";
/// No-side label on Nautilus outcome symbols.
pub const OUTCOME_SIDE_NO: &str = "NO";

/// Parses a Nautilus outcome instrument symbol of the form
/// `{outcome_index}-{YES|NO}-OUTCOME` into `(outcome_index, side)` where side
/// is `0` for Yes and `1` for No.
///

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the symbol string and fix the encoding segment so it contains only digits 0-9 (e.g. '...-42').
  2. Obtain outcome symbols from the adapter's parsed instrument definitions rather than constructing them manually.
  3. Log the raw symbol at parse time and compare against the venue's outcome metadata to find the malformed segment.
  4. If the venue changed its outcome symbol scheme, refresh instruments and update stored symbol references.

Example fix

// before
let symbol = "BTC-up-or-down-1700000000-ab"; // non-numeric encoding
let outcome = parse_outcome_symbol(symbol)?;
// after
let symbol = "BTC-up-or-down-1700000000-3"; // numeric encoding segment
let outcome = parse_outcome_symbol(symbol)?;
Defensive patterns

Strategy: validation

Validate before calling

fn is_valid_outcome_encoding(encoding: &str) -> bool {
    !encoding.is_empty() && encoding.bytes().all(|b| b.is_ascii_digit()) && encoding.parse::<u32>().is_ok()
}
// call before parse_outcome_symbol
if !is_valid_outcome_encoding(&encoding) { /* fix symbol or skip */ }

Type guard

fn valid_outcome_symbol(symbol: &str) -> Option<&str> {
    let enc = symbol.rsplit('-').next()?;
    (!enc.is_empty() && enc.bytes().all(|b| b.is_ascii_digit())).then_some(symbol)
}

Prevention

When it happens

Trigger: Calling parse_outcome_symbol (directly or via instrument/symbol parsing when subscribing or requesting data for a Hyperliquid outcome market) with a symbol whose encoding segment contains letters, dashes, spaces, or any non-digit character, e.g. '...-12x' or an empty/malformed segment that passed the earlier empty check.

Common situations: Hand-constructed outcome symbol strings, symbols copied from a different exchange's format, stale cached instrument IDs after a venue listing change, or programmatic symbol building that interpolates a non-numeric suffix.

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/098eef5004b1136b. Report an issue: GitHub.