nautechsystems/nautilus_trader · error · ValueError

Chart name cannot be empty

Error message

Chart name cannot be empty

What it means

In the metadata_changed branch (use_ts_event_for_ts_init is false but bar-type metadata was migrated, e.g. converting internal bar type metadata to external), each batch is rebuilt with RecordBatch::try_new(schema, columns) so the new schema metadata takes effect. try_new fails — and this error is raised — if the rebuilt schema's fields no longer match the batch's actual columns in count, order, or type, which can happen with arrow version differences or unexpected schema contents.

Solutions

  1. Log/diff the new schema fields against the batch columns (count, order, data types) to find the exact mismatch reported in the inner arrow error.
  2. Re-export the source data with the current NautilusTrader/arrow-rs writer version so the schema round-trips cleanly.
  3. If the mismatch is only metadata-related, rebuild the batch with SchemaRef built from batch.schema() plus new metadata instead of a reconstructed schema.
  4. Check arrow-rs changelog for RecordBatch::try_new validation changes if files come from an older ecosystem version.

Example fix

// before
*batch = RecordBatch::try_new(schema.clone(), batch.columns().to_vec())?;

// after: build schema from the batch's own fields
let new_schema = Arc::new(Schema::new(batch.schema().fields().clone())
    .with_metadata(new_metadata));
*batch = RecordBatch::try_new(new_schema, batch.columns().to_vec())?;
Defensive patterns

Strategy: try-catch

Validate before calling

// verify rebuilt schema fields equal the batch's own fields
let fields_match = schema.fields() == batch.schema().fields();
assert!(fields_match, "rebuilt schema fields must match batch columns");

Type guard

fn schema_fields_match(new: &Schema, batch: &RecordBatch) -> bool {
    new.fields() == batch.schema().fields()
}

Try / catch

match RecordBatch::try_new(schema.clone(), batch.columns().to_vec()) {
    Err(e) => {
        // fall back to batch's own fields + new metadata, or log and skip
    }
    Ok(b) => *batch = b,
}

Prevention

When it happens

Trigger: Converting stream data where convert_bar_type_metadata_to_external changed the schema metadata, and RecordBatch::try_new rejects the rebuild because columns do not match the new schema.

Common situations: Feather/stream files written by an older arrow-rs or older NautilusTrader version whose field definitions differ subtly from what the current code reconstructs; corrupted or non-standard batch metadata in legacy recordings.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at python/nautilus_trader/analysis/tearsheet.py:297

        If name is empty or func is not callable.

    Examples
    --------
    >>> # As a decorator
    >>> @register_chart("my_custom_chart")
    ... def create_custom_chart(returns: pd.Series, **kwargs) -> go.Figure:
    ...     fig = go.Figure()
    ...     # ... custom visualization logic
    ...     return fig
    >>>
    >>> # Or called directly
    >>> register_chart("another_chart", create_custom_chart)

    """
    _require_not_none(name, "name")

    if not name.strip():
        raise ValueError("Chart name cannot be empty")

    if func is None:

        def decorator(f: Callable) -> Callable:
            if not callable(f):
                raise ValueError(f"Chart function must be callable, was {type(f)}")
            _CHART_REGISTRY[name] = f
            return f

        return decorator

    if not callable(func):
        raise ValueError(f"Chart function must be callable, was {type(func)}")

    _CHART_REGISTRY[name] = func
    return None

View on GitHub (pinned to 18893faf8b)