{"record":{"id":"b65ee82522678910","repo":"nautechsystems/nautilus_trader","slug":"custom-data-type-type-name-is-not-registered-f","errorCode":null,"errorMessage":"Custom data type \"{type_name}\" is not registered for Arrow encoding; call register_custom_data_class or ensure_custom_data_registered before writing","messagePattern":"Custom data type \"(.+?)\" is not registered for Arrow encoding; call register_custom_data_class or ensure_custom_data_registered before writing","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/persistence/src/backend/custom.rs","lineNumber":155,"sourceCode":"    };\n\n    let type_name = first_custom.data.type_name();\n    let identifier = first_custom.data_type.identifier().map(String::from);\n    let dt_meta = first_custom.data_type.metadata_string_map();\n    let data_type_json = first_custom\n        .data_type\n        .to_persistence_json()\n        .map_err(|e| anyhow::anyhow!(\"Failed to serialize data_type for persistence: {e}\"))?;\n\n    let start_ts = first_custom.data.ts_init();\n    let end_ts = data.last().map_or(start_ts, |custom| custom.data.ts_init());\n    let items: Vec<Arc<dyn CustomDataTrait>> =\n        data.into_iter().map(|c| Arc::clone(&c.data)).collect();\n\n    let batch = encode_custom_to_arrow(type_name, &items)\n        .map_err(|e| anyhow::anyhow!(\"Failed to encode custom data to Arrow: {e}\"))?\n        .ok_or_else(|| {\n            anyhow::anyhow!(\n                \"Custom data type \\\"{type_name}\\\" is not registered for Arrow encoding; \\\n                 call register_custom_data_class or ensure_custom_data_registered before writing\"\n            )\n        })?;\n    let batch =\n        augment_batch_with_data_type_column(&batch, &data_type_json, type_name, dt_meta.as_ref())?;\n\n    Ok((batch, type_name.to_string(), identifier, start_ts, end_ts))\n}\n\n/// Decodes a `RecordBatch` to Data objects based on metadata.\n///\n/// Supports both standard data types and custom data types when `allow_custom_fallback`\n/// is true (e.g. when decoding files under `custom/`). When false, unknown type names\n/// produce an error instead of attempting custom decode.\n///\n/// # Errors\n///","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/persistence/src/backend/custom.rs#L137-L173","documentation":"Thrown when encode_custom_to_arrow returns None because the custom data type was never registered for Arrow encoding. NautilusTrader requires every custom data class to be registered (register_custom_data_class / ensure_custom_data_registered) before it can be written to the catalog, since encoding depends on a per-type registered encoder.","triggerScenarios":"Calling write_custom_data_batch with a custom data type_name that has no registered encoder in the current process — registration was skipped, done in a different process/module, or the type_name string does not match the registered name.","commonSituations":"Loading data from disk or a worker process where the registration code never ran; renaming a data type class so type_name no longer matches the registration; forgetting to call register_custom_data_class during application startup before catalog writes.","solutions":["Call register_custom_data_class (or ensure_custom_data_registered) for the type before writing, at application startup.","Ensure the registration runs in the same process/runtime that performs the catalog write.","Verify the type_name used for the write exactly matches the registered type name string.","Register types defensively in a shared init module that all writers import."],"exampleFix":"// before\ncatalog.write_data(custom_items)?; // type never registered\n// after\nnautilus_persistence::ensure_custom_data_registered::<MyCustomData>();\ncatalog.write_data(custom_items)?;","handlingStrategy":"validation","validationCode":"anyhow::ensure!(is_custom_data_registered(type_name), \"register {type_name} before writing\");","typeGuard":"fn is_registered(type_name: &str) -> bool { get_custom_data_encoder(type_name).is_some() }","tryCatchPattern":"match encode_custom_to_arrow(type_name, &items) {\n    Ok(None) => { register_custom_data_class::<MyData>(); retry()? }\n    Ok(Some(b)) => proceed(b),\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Call register_custom_data_class at application startup for every custom type","Ensure registration runs in the same process as catalog writes","Keep type_name strings in one constant shared by registration and writes","Add an integration test that writes and reads each custom type"],"tags":["rust","persistence","custom-data","registration"],"backgroundTag":"missing-dependency","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}