Skip to content

[Bug] TypeError: can not serialize 'Undefined' object if generic test takes in arg description which is used in the generic test config block #11229

Open
@jeremyyeo

Description

Is this a new bug in dbt-core?

  • I believe this is a new bug in dbt-core
  • I have searched the existing issues, and I could not find an existing issue for this bug

Current Behavior

On 1.9, we started supporting the description property:

Enhancement: You can now add a description to a singular data test. Use the description property to document singular data tests. You can also use docs block to capture your test description. The enhancement is available now in the "Latest" release track in dbt Cloud, and it will be included in dbt Core v1.9.

https://docs.getdbt.com/docs/dbt-versions/2024-release-notes#october-2024

Some users have been using that description with their own generic tests already prior to this. Therefore, when upgrading from a previous version, say from 1.7 to 1.9, we run into a situation where an error arise.

Expected Behavior

No errors.

Steps To Reproduce

  1. dbt project setup:
# dbt_project.yml
name: my_dbt_project
profile: all
version: "1.0.0"
config-version: 2

models:
  my_dbt_project:
    +materialized: table

# models/schema.yml
version: 2
models:
  - name: foo
    columns:
      - name: id
        tests:
          - my_custom_test:
              description: This is a test to test something.
-- tests/generic/my_custom_test.sql
{%- test my_custom_test(model, column_name, description) -%}

{{ config(meta = {'whats_this_for': description}) }}

select 1 as c

{%- endtest -%}

-- models/foo.sql
select 1 id
  1. Parse with 1.7
$ dbt parse --no-partial-parse

00:04:13  Sending event: {'category': 'dbt', 'action': 'invocation', 'label': 'start', 'context': [<snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x1054b4c10>, <snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x1054ac690>, <snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x1054acad0>]}
00:04:13  Running with dbt=1.7.19
00:04:13  running dbt with arguments {'printer_width': '80', 'indirect_selection': 'eager', 'log_cache_events': 'False', 'write_json': 'True', 'partial_parse': 'False', 'cache_selected_only': 'False', 'profiles_dir': '/Users/jeremy/.dbt', 'version_check': 'True', 'debug': 'True', 'log_path': '/Users/jeremy/git/dbt-basic/logs', 'warn_error': 'None', 'fail_fast': 'False', 'use_colors': 'True', 'use_experimental_parser': 'False', 'no_print': 'None', 'quiet': 'False', 'log_format': 'default', 'introspect': 'True', 'static_parser': 'True', 'invocation_command': 'dbt --debug parse --no-partial-parse', 'target_path': 'None', 'warn_error_options': 'WarnErrorOptions(include=[], exclude=[])', 'send_anonymous_usage_stats': 'True'}
00:04:13  Sending event: {'category': 'dbt', 'action': 'project_id', 'label': '37dabfda-7022-4d07-9d1a-67c97f478bfe', 'context': [<snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x10434cf10>]}
00:04:13  Sending event: {'category': 'dbt', 'action': 'adapter_info', 'label': '37dabfda-7022-4d07-9d1a-67c97f478bfe', 'context': [<snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x1054a4290>]}
00:04:13  Registered adapter: postgres=1.7.19
00:04:13  checksum: a8d43cdff37d0f32d7fbe4c5c25bea4bb6c86e162f8ce8fdb1a38cdcf7495431, vars: {}, profile: , target: , version: 1.7.19
00:04:13  Partial parsing not enabled
00:04:14  Sending event: {'category': 'dbt', 'action': 'load_project', 'label': '37dabfda-7022-4d07-9d1a-67c97f478bfe', 'context': [<snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x106305ed0>]}
00:04:14  Performance info: /Users/jeremy/git/dbt-basic/target/perf_info.json
00:04:14  Resource report: {"command_name": "parse", "command_success": true, "command_wall_clock_time": 0.538501, "process_user_time": 1.229373, "process_kernel_time": 0.093879, "process_mem_max_rss": "118767616", "process_in_blocks": "0", "process_out_blocks": "0"}
00:04:14  Command `dbt parse` succeeded at 13:04:14.401713 after 0.54 seconds
00:04:14  Sending event: {'category': 'dbt', 'action': 'invocation', 'label': 'end', 'context': [<snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x1012c4c50>, <snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x1012c4b90>, <snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x1012c4c10>]}
00:04:14  Flushing usage events
  1. Parse with 1.9:
$ dbt --debug parse --no-partial-parse

00:05:02  Sending event: {'category': 'dbt', 'action': 'invocation', 'label': 'start', 'context': [<snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x107886950>, <snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x1078d1510>, <snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x1078d1a90>]}
00:05:02  Running with dbt=1.9.1
00:05:02  running dbt with arguments {'printer_width': '80', 'indirect_selection': 'eager', 'log_cache_events': 'False', 'write_json': 'True', 'partial_parse': 'False', 'cache_selected_only': 'False', 'profiles_dir': '/Users/jeremy/.dbt', 'debug': 'True', 'version_check': 'True', 'log_path': '/Users/jeremy/git/dbt-basic/logs', 'warn_error': 'None', 'fail_fast': 'False', 'use_colors': 'True', 'use_experimental_parser': 'False', 'no_print': 'None', 'quiet': 'False', 'empty': 'None', 'log_format': 'default', 'invocation_command': 'dbt --debug parse --no-partial-parse', 'warn_error_options': 'WarnErrorOptions(include=[], exclude=[])', 'static_parser': 'True', 'target_path': 'None', 'introspect': 'True', 'send_anonymous_usage_stats': 'True'}
00:05:02  Sending event: {'category': 'dbt', 'action': 'project_id', 'label': '39da2371-1abe-4e85-aa0d-1375baa80e14', 'context': [<snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x107a12c50>]}
00:05:02  Sending event: {'category': 'dbt', 'action': 'adapter_info', 'label': '39da2371-1abe-4e85-aa0d-1375baa80e14', 'context': [<snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x10517ffd0>]}
00:05:02  Registered adapter: postgres=1.9.0
00:05:02  checksum: 5e8d1596cf4eae33c11286bbb248a722d21b9f00d8a7ced8137c642517055418, vars: {}, profile: , target: , version: 1.9.1
00:05:02  Partial parsing not enabled
00:05:03  Encountered an error:
can not serialize 'Undefined' object
00:05:03  Traceback (most recent call last):
  File "/Users/jeremy/git/dbt-basic/venv_dbt_1.9.latest/lib/python3.11/site-packages/dbt/cli/requires.py", line 153, in wrapper
    result, success = func(*args, **kwargs)
                      ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeremy/git/dbt-basic/venv_dbt_1.9.latest/lib/python3.11/site-packages/dbt/cli/requires.py", line 103, in wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeremy/git/dbt-basic/venv_dbt_1.9.latest/lib/python3.11/site-packages/dbt/cli/requires.py", line 235, in wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeremy/git/dbt-basic/venv_dbt_1.9.latest/lib/python3.11/site-packages/dbt/cli/requires.py", line 264, in wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeremy/git/dbt-basic/venv_dbt_1.9.latest/lib/python3.11/site-packages/dbt/cli/requires.py", line 311, in wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeremy/git/dbt-basic/venv_dbt_1.9.latest/lib/python3.11/site-packages/dbt/cli/requires.py", line 327, in wrapper
    setup_manifest(ctx, write=write, write_perf_info=write_perf_info)
  File "/Users/jeremy/git/dbt-basic/venv_dbt_1.9.latest/lib/python3.11/site-packages/dbt/cli/requires.py", line 351, in setup_manifest
    ctx.obj["manifest"] = parse_manifest(
                          ^^^^^^^^^^^^^^^
  File "/Users/jeremy/git/dbt-basic/venv_dbt_1.9.latest/lib/python3.11/site-packages/dbt/parser/manifest.py", line 2061, in parse_manifest
    manifest = ManifestLoader.get_full_manifest(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeremy/git/dbt-basic/venv_dbt_1.9.latest/lib/python3.11/site-packages/dbt/parser/manifest.py", line 312, in get_full_manifest
    manifest = loader.load()
               ^^^^^^^^^^^^^
  File "/Users/jeremy/git/dbt-basic/venv_dbt_1.9.latest/lib/python3.11/site-packages/dbt/parser/manifest.py", line 510, in load
    self.write_manifest_for_partial_parse()
  File "/Users/jeremy/git/dbt-basic/venv_dbt_1.9.latest/lib/python3.11/site-packages/dbt/parser/manifest.py", line 817, in write_manifest_for_partial_parse
    manifest_msgpack = self.manifest.to_msgpack(extended_mashumaro_encoder)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<string>", line 3, in __mashumaro_to_msgpack__
  File "<string>", line 91, in __mashumaro_to_msgpack__
  File "/Users/jeremy/git/dbt-basic/venv_dbt_1.9.latest/lib/python3.11/site-packages/dbt/parser/manifest.py", line 133, in extended_mashumaro_encoder
    return msgpack.packb(data, default=extended_msgpack_encoder, use_bin_type=True)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeremy/git/dbt-basic/venv_dbt_1.9.latest/lib/python3.11/site-packages/msgpack/__init__.py", line 36, in packb
    return Packer(**kwargs).pack(o)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "msgpack/_packer.pyx", line 279, in msgpack._cmsgpack.Packer.pack
  File "msgpack/_packer.pyx", line 276, in msgpack._cmsgpack.Packer.pack
  File "msgpack/_packer.pyx", line 265, in msgpack._cmsgpack.Packer._pack
  File "msgpack/_packer.pyx", line 213, in msgpack._cmsgpack.Packer._pack_inner
  File "msgpack/_packer.pyx", line 265, in msgpack._cmsgpack.Packer._pack
  File "msgpack/_packer.pyx", line 213, in msgpack._cmsgpack.Packer._pack_inner
  File "msgpack/_packer.pyx", line 265, in msgpack._cmsgpack.Packer._pack
  File "msgpack/_packer.pyx", line 213, in msgpack._cmsgpack.Packer._pack_inner
  File "msgpack/_packer.pyx", line 265, in msgpack._cmsgpack.Packer._pack
  File "msgpack/_packer.pyx", line 213, in msgpack._cmsgpack.Packer._pack_inner
  File "msgpack/_packer.pyx", line 265, in msgpack._cmsgpack.Packer._pack
  File "msgpack/_packer.pyx", line 213, in msgpack._cmsgpack.Packer._pack_inner
  File "msgpack/_packer.pyx", line 270, in msgpack._cmsgpack.Packer._pack
  File "msgpack/_packer.pyx", line 257, in msgpack._cmsgpack.Packer._pack_inner
TypeError: can not serialize 'Undefined' object

00:05:03  Resource report: {"command_name": "parse", "command_success": false, "command_wall_clock_time": 0.61428815, "process_in_blocks": "0", "process_kernel_time": 0.133286, "process_mem_max_rss": "112623616", "process_out_blocks": "0", "process_user_time": 1.021532}
00:05:03  Command `dbt parse` failed at 13:05:03.292204 after 0.61 seconds
00:05:03  Sending event: {'category': 'dbt', 'action': 'invocation', 'label': 'end', 'context': [<snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x1031c2910>, <snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x1078e2290>, <snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x10769b250>]}
00:05:03  Flushing usage events
00:05:04  An error was encountered while trying to flush usage events

Relevant log output

Environment

- OS: macOS
- Python: 3.11.9
- dbt: dbt-core==1.9.1 / dbt-postgres==1.9.0

Which database adapter are you using with dbt?

postgres

Additional Context

The workaround is to rename description to something else...

-- models/tests/generic/my_custom_test.sql
{% test my_custom_test(model, column_name, my_test_desc) %}

{{ config(meta = {'whats_this_for': my_test_desc}) }}

select 1 as c

{%- endtest -%}
# models/schema.yml

version: 2
models:
  - name: foo
    columns:
      - name: id
        tests:
          - my_custom_test:
              my_test_desc: This is a test to test something.
$ dbt --debug parse --no-partial-parse

00:07:51  Sending event: {'category': 'dbt', 'action': 'invocation', 'label': 'start', 'context': [<snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x104876ad0>, <snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x104877c50>, <snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x1048a8110>]}
00:07:51  Running with dbt=1.9.1
00:07:51  running dbt with arguments {'printer_width': '80', 'indirect_selection': 'eager', 'log_cache_events': 'False', 'write_json': 'True', 'partial_parse': 'False', 'cache_selected_only': 'False', 'profiles_dir': '/Users/jeremy/.dbt', 'fail_fast': 'False', 'version_check': 'True', 'log_path': '/Users/jeremy/git/dbt-basic/logs', 'debug': 'True', 'warn_error': 'None', 'use_colors': 'True', 'use_experimental_parser': 'False', 'no_print': 'None', 'quiet': 'False', 'empty': 'None', 'log_format': 'default', 'static_parser': 'True', 'invocation_command': 'dbt --debug parse --no-partial-parse', 'introspect': 'True', 'target_path': 'None', 'warn_error_options': 'WarnErrorOptions(include=[], exclude=[])', 'send_anonymous_usage_stats': 'True'}
00:07:51  Sending event: {'category': 'dbt', 'action': 'project_id', 'label': '9518eeed-b4b0-4044-83d3-6a902c093e0e', 'context': [<snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x104e136d0>]}
00:07:51  Sending event: {'category': 'dbt', 'action': 'adapter_info', 'label': '9518eeed-b4b0-4044-83d3-6a902c093e0e', 'context': [<snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x1029b0350>]}
00:07:51  Registered adapter: postgres=1.9.0
00:07:51  checksum: 5e8d1596cf4eae33c11286bbb248a722d21b9f00d8a7ced8137c642517055418, vars: {}, profile: , target: , version: 1.9.1
00:07:51  Partial parsing not enabled
00:07:51  Sending event: {'category': 'dbt', 'action': 'load_project', 'label': '9518eeed-b4b0-4044-83d3-6a902c093e0e', 'context': [<snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x1057f0e90>]}
00:07:51  Performance info: /Users/jeremy/git/dbt-basic/target/perf_info.json
00:07:52  Wrote artifact WritableManifest to /Users/jeremy/git/dbt-basic/target/manifest.json
00:07:52  Wrote artifact SemanticManifest to /Users/jeremy/git/dbt-basic/target/semantic_manifest.json
00:07:52  Resource report: {"command_name": "parse", "command_success": true, "command_wall_clock_time": 0.65783566, "process_in_blocks": "0", "process_kernel_time": 0.117218, "process_mem_max_rss": "114507776", "process_out_blocks": "0", "process_user_time": 1.064581}
00:07:52  Command `dbt parse` succeeded at 13:07:52.032242 after 0.66 seconds
00:07:52  Sending event: {'category': 'dbt', 'action': 'invocation', 'label': 'end', 'context': [<snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x100b62910>, <snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x100b628d0>, <snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x100b62a10>]}
00:07:52  Flushing usage events
00:07:53  An error was encountered while trying to flush usage events

Fwiw - debugging this problem was a super cumbersome - because the error doesn't quite point to the issue. In a project with many hundreds of models, schema yml files, macros, etc - you will never be able to find the problem as easily as described here. You will need to remove all of your project code (packages, models, yaml, macros, etc) and add things back one at a time.

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingtriage

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions