dbt-labs/dbt-core · error

type does not define keys()

Error message

{} type does not define keys()

What it means

Raised from MappedSequence.keys in the Jinja object emulation: the underlying sequence type does not provide a keys() implementation (keys() returned None), so the keys view cannot be produced. Approximates a KeyError per the code comment; the type named in the message is the at-fault input.

Solutions

  1. Call keys() only on mapped sequence types that define it (e.g. those backed by a mapping)
  2. Use items() or iterate the sequence directly when keys are unavailable
  3. Add a keys() implementation to the underlying MappedSequence subtype
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at crates/dbt-agate/src/lib.rs:714 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at crates/dbt-agate/src/lib.rs:714

                assert_nullary_args!("MappedSequence.values", args)?;
                let values = self.values();
                Ok(Value::from_object(values))
            }
            "keys" => {
                assert_nullary_args!("MappedSequence.keys", args)?;
                let keys = self
                    .keys()
                    .map(Value::from_object)
                    .unwrap_or_else(|| Value::from(()));
                Ok(keys)
            }
            "items" => {
                assert_nullary_args!("MappedSequence.items", args)?;
                if let Some(items) = self.items() {
                    Ok(Value::from_object(items))
                } else {
                    // trying to approximate a `raise KeyError`
                    Err(minijinja::Error::new(
                        ErrorKind::NonKey,
                        format!("{} type does not define keys()", self.type_name()),
                    ))
                }
            }
            "get" => {
                // def get(self, key, default=None)
                let iter = ArgsIter::new("MappedSequence.get", &["key"], args);
                let key = iter.next_arg::<&Value>()?;
                let default = iter.next_kwarg::<Option<&Value>>("default")?;
                iter.finish()?;
                let value = self.get(key, default);
                Ok(value)
            }
            "dict" => {
                assert_nullary_args!("MappedSequence.items", args)?;
                if let Some(dict) = self.dict() {
                    Ok(Value::from_object(dict))

View on GitHub (pinned to 0267ce9170)