BoundaryML/baml · error
interned member `{name}` cannot be another member's child
Error message
interned member `{name}` cannot be another member's child What it means
A derive macro for BAML's interned type families rejects a plain (non-interned) member whose child is an interned member. This is structurally impossible to support because automatic conversion walkers cannot convert through a handle; only hand-written boundary conversions can. The macro fails at parse/derivation time before any code is generated.
Source
Thrown at baml_language/crates/baml_type_macros/src/parse.rs:329
let resolved_members = members
.iter()
.enumerate()
.map(|(i, m)| {
let includes = m
.includes
.iter()
.map(&axis_index)
.collect::<syn::Result<Vec<_>>>()?;
let child = match &m.child {
ChildRef::SelfRef => Child::Member(i),
ChildRef::Named(name) => {
let idx = member_index(name)?;
// A plain member cannot nest an interned member: the
// structural conversion walkers would have to convert
// through a handle, which only the hand-written
// boundary conversions can do.
if matches!(members[idx].child, ChildRef::Interned(_)) {
return Err(syn::Error::new(
name.span(),
format!(
"interned member `{name}` cannot be another member's child"
),
));
}
Child::Member(idx)
}
ChildRef::Interned(handle) => {
if m.name == master_ident {
return Err(syn::Error::new(
m.name.span(),
"the master member cannot be interned: the master is the \
plain tree every other member converts through",
));
}
Child::Interned(Box::new(handle.clone()))
}View on GitHub (pinned to bd85ce9dee)
Solutions
- Make the child member plain (remove its interning) so nesting stays in the walker-convertible plain tree.
- Convert the parent into an interned member too, so the nesting lives behind a handle processed by boundary conversions.
- Restructure so interned members only appear at the top level, not as children of other members.
Example fix
// before
member Plain {
child: InternedMember,
}
// after
member Plain {
child: PlainChild,
}
member PlainChild { /* plain fields */ } Defensive patterns
Strategy: validation
Validate before calling
// at macro-input authoring time
assert!(!members.iter().any(|m| matches!(m.child, ChildRef::Interned(_))),
"plain members must not nest interned members"); Type guard
fn is_plain_child(m: &Member) -> bool { !matches!(m.child, ChildRef::Interned(_)) } Prevention
- Keep interned members at the top level of the family only
- Document which members are interned in the type-family definition
- Run the derive on a minimal fixture in CI to catch structure errors early
When it happens
Trigger: Declaring a derive input where `member_index(name)` resolves to a member whose `ChildRef` is `ChildRef::Interned(_)` — i.e. writing a plain member that nests another member marked as interned.
Common situations: Developers mixing plain and interned members in one type-family definition, assuming arbitrary nesting works; or refactoring a plain tree to add interning and marking the wrong level interned.
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
- the master member cannot be interned: the master is the plai
- unknown axis `{name}`
- unknown family member `{name}`
- variant `{}` has more than one `#[axis(..)]`
- variant `{}` must declare exactly one `#[axis(..)]`
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/eff13888796f9ff1.
Report an issue: GitHub.