dbt-labs/dbt-core · error · minijinja::Error::InvalidArgument

quote_key must be one of: database, schema, identifier

Error message

quote_key must be one of: database, schema, identifier

What it means

`quote_as_configured` takes a `quote_key` string that must parse into a `ComponentName` (database, schema, or identifier). When parsing fails the adapter raises this InvalidArgument error listing the valid values. It prevents arbitrary quoting keys from reaching the quoting policy logic.

Solutions

  1. Use only the literal strings 'database', 'schema', or 'identifier' as quote_key
  2. If the key comes from config, validate/normalize it (lowercase, trim) before calling
  3. Add a Jinja-side check that raises a clearer message when the configured quoting component is unrecognized

Example fix

// before
adapter.quote_as_configured(name, "Schema")
// after
adapter.quote_as_configured(name, "schema")
Defensive patterns

Strategy: validation

Validate before calling

// guard before calling
const VALID: [&str; 3] = ["database", "schema", "identifier"];
if !VALID.contains(&quote_key) {
    return Err(format!("quote_key '{quote_key}' invalid; must be database|schema|identifier"));
}

Type guard

fn is_valid_quote_key(k: &str) -> bool {
    matches!(k, "database" | "schema" | "identifier")
}

Try / catch

let quote_key = quote_key.parse::<ComponentName>().map_err(|_| {
    minijinja::Error::new(minijinja::ErrorKind::InvalidArgument,
        "quote_key must be one of: database, schema, identifier")
})?;

Prevention

When it happens

Trigger: Calling adapter.quote_as_configured(identifier, quote_key) with quote_key not exactly one of 'database', 'schema', 'identifier' — e.g. a typo like 'schema_name', mixed case, or a dynamically built key from config.

Common situations: Macros or custom materializations compute the quoting component from Jinja config values; a missing/renamed config yields an unexpected key string that fails ComponentName::from_str.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07). Data as JSON: /api/errors/5b9cf84c146b8365. Report an issue: GitHub.

Appendix: source

Thrown at crates/dbt-adapter/src/adapter/mod.rs:635

    ///     identifier: str,
    ///     quote_key: str
    /// ) -> str
    /// ```
    #[tracing::instrument(skip_all, level = "trace")]
    pub fn quote_as_configured(
        &self,
        state: &State,
        args: &[Value],
    ) -> Result<Value, minijinja::Error> {
        match &self.inner {
            Typed { adapter, .. } => {
                let iter = ArgsIter::new("quote_as_configured", &["identifier", "quote_key"], args);
                let identifier = iter.next_arg::<&str>()?;
                let quote_key = iter.next_arg::<&str>()?;
                iter.finish()?;

                let quote_key = quote_key.parse::<ComponentName>().map_err(|_| {
                    minijinja::Error::new(
                        minijinja::ErrorKind::InvalidArgument,
                        "quote_key must be one of: database, schema, identifier",
                    )
                })?;

                let result = adapter.quote_as_configured(state, identifier, &quote_key)?;

                Ok(Value::from(result))
            }
            Parse(_) => Ok(empty_string_value()),
        }
    }

    /// Quote seed column.
    ///
    /// https://github.com/dbt-labs/dbt-adapters/blob/5fba80c621c3f0f732dba71aa6cf9055792b6495/dbt-adapters/src/dbt/adapters/base/impl.py#L1091
    ///
    /// ```python

View on GitHub (pinned to 0267ce9170)