{"record":{"id":"3f6596824018fe8e","repo":"nautechsystems/nautilus_trader","slug":"unknown-data-type-type-name-custom-decode-only","errorCode":null,"errorMessage":"Unknown data type: {type_name}; custom decode only allowed in custom data context","messagePattern":"Unknown data type: (.+?); custom decode only allowed in custom data context","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/persistence/src/backend/custom.rs","lineNumber":221,"sourceCode":"        \"IndexPriceUpdate\" | \"index_price_updates\" => {\n            Ok(IndexPriceUpdate::decode_data_batch(metadata, batch)?)\n        }\n        \"OptionGreeks\" | \"option_greeks\" => Ok(OptionGreeks::decode_data_batch(metadata, batch)?),\n        \"InstrumentClose\" | \"instrument_closes\" => {\n            Ok(InstrumentClose::decode_data_batch(metadata, batch)?)\n        }\n        _ => {\n            if allow_custom_fallback {\n                #[cfg(feature = \"python\")]\n                {\n                    return Ok(CustomDataDecoder::decode_data_batch(metadata, batch)?);\n                }\n                #[cfg(not(feature = \"python\"))]\n                {\n                    anyhow::bail!(\"Unknown data type: {type_name}\");\n                }\n            }\n            anyhow::bail!(\n                \"Unknown data type: {type_name}; custom decode only allowed in custom data context\"\n            )\n        }\n    }\n}\n\n/// Decodes multiple `RecordBatches` (e.g. from custom data files) into a single `Vec<Data>`.\n/// Optionally replaces `ts_init` column with `ts_event` before decoding each batch.\n///\n/// # Errors\n///\n/// Returns an error if any batch fails to decode.\npub fn decode_custom_batches_to_data(\n    batches: Vec<RecordBatch>,\n    use_ts_event_for_ts_init: bool,\n) -> anyhow::Result<Vec<Data>> {\n    let mut file_data = Vec::new();\n    let schema = batches","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/persistence/src/backend/custom.rs#L203-L239","documentation":"decode_batch_to_data raises this when the batch's type name is not a known custom type, indicating the batch was routed to the custom decoder path but its type is not registered for custom decoding. Custom decode is only allowed for types in the custom data context, so foreign/unknown types are rejected here.","triggerScenarios":"Calling decode_custom_batches_to_data with record batches whose metadata type_name is not a registered custom type (wrong context routing, mixed batches, or a type name typo in file metadata).","commonSituations":"Passing built-in type batches (Quote/Trade) into the custom decode path accidentally; catalogs written by a different version with unregistered custom types; manually edited or migrated Parquet metadata.","solutions":["Ensure only batches with registered custom type names go through decode_custom_batches_to_data; decode built-in types via their normal path.","Register the custom data type before decoding so the type name resolves.","Verify the type_name stored in the Parquet metadata matches the registered custom type exactly (check for typos/case).","Re-export the data from the original writer version if metadata names differ."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// route batches by type before decoding\nlet (custom, builtin): (Vec<_>, Vec<_>) = batches\n    .into_iter()\n    .partition(|b| batch_type_name(b).starts_with(\"custom/\"));\n// decode custom via decode_custom_batches_to_data, builtin via the standard path","typeGuard":"fn is_custom_batch(b: &RecordBatchMeta) -> bool {\n    b.type_name().starts_with(\"custom/\") && is_registered_custom_type(b.type_name())\n}","tryCatchPattern":"match decode_custom_batches_to_data(batches) {\n    Err(e) if e.to_string().contains(\"custom decode only allowed\") => {\n        // reroute batch to the built-in decode path\n    }\n    other => other?,\n}","preventionTips":["Only pass batches whose type_name is a registered custom type into the custom decoder.","Register all custom types before reading the catalog.","Validate Parquet metadata type_name strings after catalog migration/rewrites."],"tags":["rust","persistence","decoding","custom-data"],"backgroundTag":"unsupported-enum-value","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"}