{"record":{"id":"d80ca27c5271f06c","repo":"nautechsystems/nautilus_trader","slug":"name-must-not-be-none","errorCode":null,"errorMessage":"{name} must not be None","messagePattern":"(.+?) must not be None","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/nautilus_trader/analysis/tearsheet.py","lineNumber":107,"sourceCode":"    if not TYPE_CHECKING:\n        go = None  # type: ignore[assignment]\n\n\nTRADING_DAYS_PER_YEAR = 252\n\n_GRID_ONE_ROW_MAX_CHARTS = 2\n_GRID_TWO_ROWS_MAX_CHARTS = 4\n_GRID_THREE_ROWS_MAX_CHARTS = 6\n_GRID_DEFAULT_ROWS = 4\n\n_STATIC_IMAGE_SUFFIXES = frozenset({\".png\", \".jpg\", \".jpeg\", \".webp\", \".svg\", \".pdf\"})\n\n_CHART_REGISTRY: dict[str, Callable] = {}\n\n\ndef _require_not_none(value: object, name: str) -> None:\n    if value is None:\n        raise ValueError(f\"{name} must not be None\")\n\n\ndef _format_optional_iso8601(timestamp_ns: int | None) -> str:\n    if timestamp_ns is None:\n        return \"N/A\"\n    return unix_nanos_to_iso8601(timestamp_ns, nanos_precision=False)\n\n\ndef _format_optional_duration(start_ns: int | None, end_ns: int | None) -> str:\n    if start_ns is None or end_ns is None:\n        return \"N/A\"\n    return str(pd.Timedelta(end_ns - start_ns, unit=\"ns\"))\n\n\ndef _to_returns_series(returns: pd.Series | Mapping | list | None) -> pd.Series:\n    pandas: Any = _require_pandas()\n    if returns is None:\n        return pandas.Series(dtype=float)","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/python/nautilus_trader/analysis/tearsheet.py#L89-L125","documentation":"After copying ts_event into the ts_init slot, apply_stream_conversion_transforms rebuilds each RecordBatch with RecordBatch::try_new(schema, columns). arrow's try_new validates that every column matches the schema (field order, count, data types); any mismatch fails construction and is wrapped in this error. In this branch the only schema change is metadata (or the ts_init column swap), so a mismatch means the swapped column's type or the rebuilt schema is inconsistent.","triggerScenarios":"The ts_event and ts_init columns have different Arrow data types (e.g. ts_event is Int64/Timestamp while ts_init is UInt64), so columns[ts_init_idx] = columns[ts_event_idx].clone() violates the schema, or a schema rebuild with modified metadata no longer matches the actual columns.","commonSituations":"Legacy data where ts_event was stored as Timestamp(nanoseconds) but ts_init as UInt64 — the column copy succeeds but batch construction fails; files written by a different arrow-rs version with subtly different metadata/type handling.","solutions":["Compare the data types of ts_event and ts_init in the source schema; cast ts_event to UInt64 before assigning it to the ts_init slot if they differ.","Use arrow::compute::cast(columns[ts_event_idx].as_ref(), ts_init_type) when copying, then rebuild the batch.","If types cannot be reconciled, run the conversion without use_ts_event_for_ts_init and fix the source data.","Check that the writer that produced the data used a compatible arrow-rs version (type-level mismatch often comes from version drift)."],"exampleFix":"// before\ncolumns[ts_init_idx] = columns[ts_event_idx].clone();\n\n// after\ncolumns[ts_init_idx] = arrow::compute::cast(\n    columns[ts_event_idx].as_ref(),\n    schema.field(ts_init_idx).data_type(),\n)?;","handlingStrategy":"type-guard","validationCode":"let ts_event_t = batch.schema().field_with_name(\"ts_event\")?.data_type();\nlet ts_init_t = batch.schema().field_with_name(\"ts_init\")?.data_type();\nassert_eq!(ts_event_t, ts_init_t, \"ts_event/ts_init type mismatch prevents column swap\");","typeGuard":"fn columns_swappable(batch: &RecordBatch) -> bool {\n    let s = batch.schema();\n    match (s.field_with_name(\"ts_event\"), s.field_with_name(\"ts_init\")) {\n        (Ok(a), Ok(b)) => a.data_type() == b.data_type(),\n        _ => false,\n    }\n}","tryCatchPattern":"match RecordBatch::try_new(schema.clone(), columns) {\n    Err(e) => return Err(anyhow::anyhow!(\"cast ts_event to ts_init type before swap: {e}\")),\n    Ok(b) => b,\n}","preventionTips":["Cast ts_event to ts_init's data type before copying the column","Ensure writers emit both timestamp columns as UInt64","Pin/align arrow-rs versions between writer and converter"],"tags":["arrow","recordbatch","type-mismatch","schema","data-conversion"],"backgroundTag":"schema-validation-failed","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}