SeaQL/sea-orm · error

Reference column is not set

Error message

Reference column is not set

What it means

Converting a `RelationBuilder` into a `RelationDef` requires the `from_col` (reference column) to have been set via `from_col()`/`from()`. If the builder never received it, the `From` impl panics with 'Reference column is not set'. Relations fundamentally need both sides' columns to generate joins and foreign keys.

Source

Thrown at sea-orm-sync/src/entity/relation.rs:472

    /// Combine the column equality and [`on_condition`](Self::on_condition)
    /// with `AND` (`ConditionType::All`, default) or `OR` (`ConditionType::Any`).
    pub fn condition_type(mut self, condition_type: ConditionType) -> Self {
        self.condition_type = condition_type;
        self
    }
}

impl<E, R> From<RelationBuilder<E, R>> for RelationDef
where
    E: EntityTrait,
    R: EntityTrait,
{
    fn from(b: RelationBuilder<E, R>) -> Self {
        RelationDef {
            rel_type: b.rel_type,
            from_tbl: b.from_tbl,
            to_tbl: b.to_tbl,
            from_col: b.from_col.expect("Reference column is not set"),
            to_col: b.to_col.expect("Owner column is not set"),
            is_owner: b.is_owner,
            skip_fk: b.skip_fk,
            on_delete: b.on_delete,
            on_update: b.on_update,
            on_condition: b.on_condition,
            fk_name: b.fk_name,
            condition_type: b.condition_type,
        }
    }
}

macro_rules! set_foreign_key_stmt {
    ( $relation: ident, $foreign_key: ident ) => {
        let from_cols: Vec<String> = $relation
            .from_col
            .into_iter()
            .map(|col| {

View on GitHub (pinned to e29bcd1b41)

Solutions

  1. Call `.from_col(ColumnRef/Identity)` on the builder before converting it into a RelationDef.
  2. Validate relation config data before building: ensure both reference and owner columns exist.
  3. Use generated entity relations (`Entity::has_many(...)` macros) which always populate both columns.

Example fix

// before
let rel = Relation::HasMany.to(R::default()).into();
// after
let rel = Relation::HasMany.to(R::default()).from_col(user::Column::Id).into();
Defensive patterns

Strategy: validation

Validate before calling

// before converting a builder to RelationDef
let def = Relation::HasMany.to(target)
    .from_col(src_col) // must be set
    .to_col(target_col);
assert!(matches!(def, _)); // compile-time builder chaining guarantees both columns

Type guard

fn relation_complete(b: &RelationBuilder<impl EntityTrait, impl Related<impl EntityTrait>>) -> bool { true } // prefer typed builder chain so missing cols cannot compile

Prevention

When it happens

Trigger: Programmatically constructing a relation with `Relation::new()`/`has_many(...)` style builders and forgetting the `.from_col(...)` call before converting to `RelationDef` (e.g. in custom schema/migration code or dynamic relation construction).

Common situations: Writing custom migrations or schema helpers that assemble relations at runtime; dynamic query builders assembling joins from config where a column key is missing.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of SeaQL/sea-orm@e29bcd1b41 (2026-09-10). Data as JSON: /api/errors/67bbcffa29695a9a. Report an issue: GitHub.