diesel-rs/diesel · error · syn::Error

expected `foreign_key`

Error message

expected `foreign_key`

What it means

Compile-time error from the deprecated #[belongs_to(...)] attribute parser. After the parent model name, the only additional option accepted in the old syntax is `foreign_key = "..."`; any other trailing identifier (e.g. a misspelled `foreignkeys`) is rejected with this sentinel. Fires when parsing arguments of #[belongs_to(Parent, ...)] during the deprecated attribute path. Fix: use `foreign_key` or drop the extra argument.

Solutions

  1. Use `foreign_key = "..."` in the attribute
  2. Remove the unrecognized argument and keep only supported keys
  3. Prefer the modern non-deprecated attribute form

Example fix

// before
#[diesel(belongs_to(User, fk = "author_id"))]
// after
#[diesel(belongs_to(User, foreign_key = "author_id"))]
Defensive patterns

Strategy: validation

Validate before calling

// only allowed option inside belongs_to(...): foreign_key = "..."

Prevention

When it happens

Trigger: Writing `#[diesel(belongs_to(User, some_other_key = "x"))]` or any option other than `foreign_key = "..."` inside the parentheses.

Common situations: Guessing option names, using options from newer diesel versions that the old deprecated parser does not know, or typos like `foreignkeys`/`foreign-key`.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of diesel-rs/diesel@6fa6ed01b2 (2026-09-07). Data as JSON: /api/errors/0136db0e913c753a. Report an issue: GitHub.

Appendix: source

Thrown at diesel_attribute_parser/src/deprecated/belongs_to.rs:44

        if name == "parent" {
            let lit_str = parse_eq_and_lit_str(name, &content, BELONGS_TO_NOTE)?;
            lit_str.parse()?
        } else {
            LitStr::new(&name.to_string(), name.span()).parse()?
        }
    } else {
        content.parse()?
    };

    let mut foreign_key = None;

    if content.peek(Comma) {
        content.parse::<Comma>()?;

        let name: Ident = content.parse()?;

        if name != "foreign_key" {
            return Err(syn::Error::new(name.span(), "expected `foreign_key`"));
        }

        let lit_str = parse_eq_and_lit_str(name, &content, BELONGS_TO_NOTE)?;
        foreign_key = Some(lit_str.parse()?);
    }

    Ok(BelongsTo {
        parent,
        foreign_key,
    })
}

View on GitHub (pinned to 6fa6ed01b2)