nautechsystems/nautilus_trader · critical

invalid `AggregationSource` enum string value, was '{value}'

Error message

invalid `AggregationSource` enum string value, was '{value}'

What it means

FFI helper aggregation_source_from_cstr converts a C string to the AggregationSource enum and panics (aborting via abort_on_panic) when the value does not parse. As with all FFI boundary panics, the process aborts rather than unwinding, so the host cannot recover.

Source

Thrown at crates/model/src/ffi/enums.rs:318

pub extern "C" fn aggregation_source_to_cstr(value: AggregationSource) -> *const c_char {
    str_to_cstr(value.as_ref())
}

/// Returns an enum from a C string.
///
/// # Safety
///
/// Assumes `ptr` is a valid C string pointer.
///
/// # Panics
///
/// Panics if the C string does not correspond to a valid `AggregationSource` variant.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn aggregation_source_from_cstr(ptr: *const c_char) -> AggregationSource {
    abort_on_panic(|| {
        let value = unsafe { cstr_as_str(ptr) };
        AggregationSource::from_str(value).unwrap_or_else(|_| {
            panic!("invalid `AggregationSource` enum string value, was '{value}'")
        })
    })
}

#[unsafe(no_mangle)]
pub extern "C" fn aggressor_side_to_cstr(value: AggressorSide) -> *const c_char {
    str_to_cstr(value.as_ref())
}

/// Returns an enum from a C string.
///
/// # Safety
///
/// Assumes `ptr` is a valid C string pointer.
///
/// # Panics
///
/// Panics if the C string does not correspond to a valid `AggressorSide` variant.

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Use the exact accepted AggregationSource strings (check the Rust enum's FromStr impl)
  2. Validate the string in the host language before crossing the FFI boundary
  3. Regenerate/sync bindings after upgrading nautilus_model

Example fix

// before
let src = aggregation_source_from_cstr(c"external"); // invalid -> abort
// after
let src = aggregation_source_from_cstr(c"EXTERNAL"); // must match enum values exactly
Defensive patterns

Strategy: validation

Validate before calling

// Host-side validation before the FFI call
VALID_SOURCES = {"NO_INTERNET", "INTERNET"}  # match AggregationSource variants
if value not in VALID_SOURCES:
    raise ValueError(f"invalid AggregationSource: {value!r}")

Try / catch

// FFI panics abort, so validate before crossing the boundary
assert!(VALID.contains(&value.as_str()), "invalid AggregationSource: {value}");
let source = unsafe { aggregation_source_from_cstr(ptr) };

Prevention

When it happens

Trigger: Passing a C string that is not a valid AggregationSource variant (e.g. 'EXTERNAL' vs expected 'NO_INTERNET'/'INTERNET' style values) to aggregation_source_from_cstr.

Common situations: Config strings from another system using different naming for data aggregation source; stale bindings after an enum rename; typos or lowercasing in config files consumed by the C/Python layer.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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