nautechsystems/nautilus_trader · error
Custom data type "{type_name}" is already registered for Arr
Error message
Custom data type "{type_name}" is already registered for Arrow What it means
register_arrow inserts an Arrow schema/encoder/decoder triple into the custom-data registry keyed by type name. Duplicate type names are rejected with this error rather than overwriting an existing registration, keeping the Arrow encode/decode path deterministic.
Source
Thrown at crates/model/src/data/registry.rs:169
};
Ok(Some(Data::Custom(custom)))
}
/// Registers Arrow schema, encoder, and decoder for the given custom data type name.
///
/// # Errors
/// Returns an error if the type is already registered for Arrow.
#[cfg(feature = "arrow")]
pub fn register_arrow(
type_name: &str,
schema: Arc<Schema>,
encoder: ArrowEncoder,
decoder: ArrowDecoder,
) -> Result<(), anyhow::Error> {
let reg = registries();
match reg.arrow.entry(type_name.to_string()) {
Entry::Occupied(_) => {
anyhow::bail!("Custom data type \"{type_name}\" is already registered for Arrow");
}
Entry::Vacant(v) => {
v.insert((schema, encoder, decoder));
Ok(())
}
}
}
/// Registers Arrow schema, encoder, and decoder for the given custom data type name if not already
/// registered. If the type is already registered, returns `Ok(())` without overwriting (idempotent).
/// Use this where repeated registration can occur (e.g. module init).
///
/// # Errors
/// Does not return an error (idempotent insert into `DashMap`).
#[cfg(feature = "arrow")]
pub fn ensure_arrow_registered(
type_name: &str,
schema: Arc<Schema>,View on GitHub (pinned to 18893faf8b)
Solutions
- Make registration idempotent (Once lock, checked init, or catch-and-ignore this specific error when the registration is identical).
- Ensure the encoder/decoder/schema setup runs exactly once per process.
- Rename the type if a genuine conflict between different types exists.
Example fix
// before
register_arrow("MyData", schema, enc, dec)?;
// after
if let Err(e) = register_arrow("MyData", schema, enc, dec) {
if !e.to_string().contains("already registered") { return Err(e); }
} Defensive patterns
Strategy: try-catch
Validate before calling
// Rust — guard with process-wide init static ARROW_INIT: OnceLock<()> = OnceLock::new(); // call inside: ARROW_INIT.get_or_init(|| register_arrow(name, schema, enc, dec).unwrap());
Try / catch
// Rust
match register_arrow(type_name, schema, enc, dec) {
Ok(()) => (),
Err(e) if e.to_string().contains("already registered for Arrow") => (), // treat as success
Err(e) => return Err(e),
} Prevention
- Wrap Arrow registration in a Once-style initializer so repeats are no-ops.
- In tests, register in a setup function that runs once, or tolerate duplicates.
- Document ownership of each type's Arrow registration to avoid cross-crate collisions.
When it happens
Trigger: Calling register_arrow twice with the same type_name — repeated initialization, module re-import in Python, or two crates registering Arrow support for the same type.
Common situations: Test suites running registration per test; notebook re-runs; adapter reload logic that lacks an idempotence guard.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- Custom data type "{type_name}" is already registered for JSO
- Custom data type "{type_name}" is already registered for Pyt
- Rust extractor factory for "{type_name}" is already register
- height must be positive, was {self.height}
- pandas is required for report generation; install it with `p
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/7ad1f7fa5819901c.
Report an issue: GitHub.