facebook/relay · error

Expected docblocks to only expose object and scalar definiti

Error message

Expected docblocks to only expose object and scalar definitions, and object and interface extensions.

What it means

mark_extension_as_base panics on any TypeSystemDefinition other than object/scalar definitions or object/interface extensions. Docblock-driven schema extensions are limited to that set; anything else (e.g. union/enum extensions) should have been filtered earlier.

Source

Thrown at compiler/crates/relay-compiler/src/build_project/build_resolvers_schema/mark_document_as_base.rs:69

                    &def.directives,
                    &[belongs_to_base_schema_directive()],
                ),
                ..def
            })
        }
        TypeSystemDefinition::ObjectTypeExtension(def) => {
            TypeSystemDefinition::ObjectTypeExtension(ObjectTypeExtension {
                fields: mark_fields_as_base(def.fields),
                ..def
            })
        }
        TypeSystemDefinition::InterfaceTypeExtension(def) => {
            TypeSystemDefinition::InterfaceTypeExtension(InterfaceTypeExtension {
                fields: mark_fields_as_base(def.fields),
                ..def
            })
        }
        _ => panic!(
            "Expected docblocks to only expose object and scalar definitions, and object and interface extensions."
        ),
    }
}

/// Mark fields as base schema extension fields
fn mark_fields_as_base(fields: Option<List<FieldDefinition>>) -> Option<List<FieldDefinition>> {
    fields.map(|list| List {
        items: list
            .items
            .iter()
            .map(|item| FieldDefinition {
                directives: merge_directives(
                    &item.directives,
                    &[belongs_to_base_schema_directive()],
                ),
                ..item.clone()
            })

View on GitHub (pinned to 668b1b85e0)

Solutions

  1. Restrict docblock extensions to objects/scalars (definitions) and object/interface extensions
  2. Convert the union/enum extension into a full definition or a supported extension form
  3. Report upstream if a supported construct reaches this panic (parser/mark step contract violation)
Defensive patterns

Strategy: validation

Validate before calling

// Filter unsupported definitions before calling mark_extension_as_base
let supported = matches!(def,
    TypeSystemDefinition::ObjectType(_) | TypeSystemDefinition::ScalarType(_)
      | TypeSystemDefinition::ObjectTypeExtension(_)
      | TypeSystemDefinition::InterfaceTypeExtension(_));
if !supported { return Err("unsupported docblock schema definition"); }

Type guard

fn is_markable(d: &TypeSystemDefinition) -> bool {
    matches!(d,
        TypeSystemDefinition::ObjectType(_)
        | TypeSystemDefinition::ScalarType(_)
        | TypeSystemDefinition::ObjectTypeExtension(_)
        | TypeSystemDefinition::InterfaceTypeExtension(_))
}

Try / catch

// not catchable; guard with is_markable and surface an unsupported-extension diagnostic

Prevention

When it happens

Trigger: A docblock produces a schema definition/extension of an unsupported kind (e.g. a union or enum extension) that reaches mark_extension_as_base during mark_document_as_base.

Common situations: A resolver docblock tries to extend a union or enum, or the docblock parser emits extension kinds the base-marking step doesn't support.

Related errors


AI-assisted analysis of facebook/relay@668b1b85e0 (2026-09-02). Data as JSON: /api/errors/18a89d3d43aaa1dc. Report an issue: GitHub.