{"record":{"id":"5adf9d539141cdbf","repo":"dbt-labs/dbt-core","slug":"zip-requires-at-least-1-argument","errorCode":null,"errorMessage":"zip requires at least 1 argument","messagePattern":"zip requires at least 1 argument","errorType":"validation","errorClass":"InvalidOperation","httpStatus":null,"severity":"error","filePath":"crates/dbt-jinja-utils/src/functions/base.rs","lineNumber":838,"sourceCode":"\n/// Return an iterator of tuples where each tuple contains the i-th element from each of the input iterables.\n/// dbt's zip also supports a custom kwarg `fillvalue` (default=None) to match the longest iterable.\n///\n/// Args:\n///     *iterables: Two or more iterables\n///     fillvalue: (optional) Value to fill in shorter iterables, default=None\n///\n/// Example:\n/// ```jinja\n/// {% set list1 = [1, 2] %}\n/// {% set list2 = ['a', 'b', 'c'] %}\n/// {% set pairs = zip(list1, list2, fillvalue='N/A') %}\n/// -- Returns [(1, 'a'), (2, 'b'), ('N/A', 'c')]\n/// ```\npub fn zip_fn() -> impl Fn(&[Value], Kwargs) -> Result<Value, Error> {\n    move |args: &[Value], kwargs: Kwargs| -> Result<Value, Error> {\n        if args.is_empty() {\n            return Err(Error::new(\n                ErrorKind::InvalidOperation,\n                \"zip requires at least 1 argument\",\n            ));\n        }\n\n        let default = match (kwargs.get::<Value>(\"default\"), args.get(1)) {\n            (Ok(value), _) => Some(value),\n            (_, Some(value)) => Some(value.clone()),\n            _ => None,\n        };\n\n        // Try to convert each argument to an internal Vec<Value>\n        let mut iterators: Vec<Vec<Value>> = Vec::new();\n        for arg in args {\n            match arg.try_iter() {\n                Ok(iter) => iterators.push(iter.collect()),\n                Err(_) => return Ok(default.unwrap_or_else(|| Value::from(()))),\n            }","sourceCodeStart":820,"sourceCodeEnd":856,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-jinja-utils/src/functions/base.rs#L820-L856","documentation":"zip() combines two or more sequences element-wise (optionally with a fillvalue/default for uneven lengths, matching Python's itertools.zip_longest). It requires at least one positional argument; calling it with none throws this InvalidOperation error before any zipping happens.","triggerScenarios":"Calling zip() with zero positional arguments, e.g. a dynamically built argument list that ended up empty, or zip(default='N/A') with kwargs only.","commonSituations":"Lists built via template loops that turned out empty-of-arguments rather than being empty lists; refactors dropping the list arguments; confusion between the 'default' kwarg and positional fillvalue handling.","solutions":["Pass at least two lists to zip: zip(list1, list2)","If lists may be absent, guard: zip(list1, list2) only when both are defined and sequences","Pass empty lists instead of omitting arguments: zip([], [])"],"exampleFix":"// before\n{% set pairs = zip() %}\n// after\n{% set pairs = zip(list1 or [], list2 or []) %}","handlingStrategy":"validation","validationCode":"{% if list1 is not sequence or list2 is not sequence %}\n  {{ exceptions.raise_compiler_error('zip needs at least two lists in ' ~ this) }}\n{% endif %}\n{% set pairs = zip(list1, list2) %}","typeGuard":"{% macro zip_safe(a, b) %}{{ return(zip(a if a is sequence else [], b if b is sequence else [])) }}{% endmacro %}","tryCatchPattern":null,"preventionTips":["Never call zip() with zero positional arguments; pass [] instead","Coalesce undefined lists: list1 or []","Verify dynamic argument lists actually contain arguments before calling"],"tags":["jinja","dbt","argument-count"],"backgroundTag":"missing-required-argument","analyzedSha":"0267ce9170576975b76b64ce856b2e5848e96617","analyzedAt":"2026-09-07T21:53:39.732Z","contentChangedAt":"2026-09-07T21:53:39.732Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}