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

only single feature `cfg_attr` attributes are supported. Got

Error message

only single feature `cfg_attr` attributes are supported. Got `{ident}` but expected `feature = "foo"`

What it means

The `cfg_attr` option of `#[sql_function]` supports only single-feature conditions of the form `feature = "foo"`. If the first token inside `cfg_attr(...)` is not the identifier `feature`, the macro rejects it with this message.

Solutions

  1. Use exactly `feature = "foo"` as the cfg_attr predicate: `cfg_attr(feature = "foo", ...)`
  2. Fix typos like `features` or `feat`
  3. Move complex cfg conditions outside the macro and gate the function definition itself with a normal `#[cfg_attr]`

Example fix

// before
#[sql_function(cfg_attr(unix, prefix = "pg_"))]
// after
#[sql_function(cfg_attr(feature = "postgres", prefix = "pg_"))]
Defensive patterns

Strategy: validation

Validate before calling

fn validate_cfg_attr_predicate(pred: &str) -> Result<(), String> {
    if pred.starts_with("feature = \"") && pred.ends_with("\"") { Ok(()) } else { Err(format!("cfg_attr predicate must be feature = \"foo\", got: {}", pred)) }
}

Type guard

fn is_single_feature_cfg(pred: &str) -> bool { pred.starts_with("feature = \"") && pred.ends_with("\"") }

Prevention

When it happens

Trigger: Using `#[sql_function(cfg_attr(...))]` where the predicate does not start with `feature`, e.g. `cfg_attr(unix, ...)` or `cfg_attr(target_os = "...", ...)` or a misspelled `features = "foo"`.

Common situations: Copying general `#[cfg_attr]` conditions into the proc-macro attribute, which only implements a small subset of cfg syntax; trying multi-feature or `all()` conditions.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at diesel_derives/src/sql_function.rs:1939

            ident.span(),
            format!("Expected `require_order` but got `{ident}`"),
        ))
    }
}

impl SqlFunctionAttribute {
    fn parse_attr(
        name: Ident,
        input: &syn::parse::ParseBuffer<'_>,
        attr: Attribute,
        attribute_span: proc_macro2::Span,
    ) -> Result<AttributeSpanWrapper<Self>> {
        // rustc doesn't resolve cfg attrs for us :(
        // This is hacky, but mostly for internal use
        if name == "cfg_attr" {
            let ident = input.parse::<Ident>()?;
            if ident != "feature" {
                return Err(syn::Error::new(
                    ident.span(),
                    format!(
                        "only single feature `cfg_attr` attributes are supported. \
                             Got `{ident}` but expected `feature = \"foo\"`"
                    ),
                ));
            }
            let _ = input.parse::<Token![=]>()?;
            let feature = input.parse::<LitStr>()?;
            let feature_value = feature.value();
            let _ = input.parse::<Token![,]>()?;
            let wrap_macro = match feature_value.as_str() {
                "postgres_backend" => Some(syn::parse_quote!(
                    diesel::internal::sql_functions::expand_pg
                )),
                "sqlite" | "__sqlite_shared" => Some(syn::parse_quote!(
                    diesel::internal::sql_functions::expand_sqlite
                )),

View on GitHub (pinned to 6fa6ed01b2)