Skip to content

Make a null in an include or a target remove the value it overrides - #7261

Draft
denik wants to merge 5 commits into
denik/null-merging-testsfrom
denik/null-merging
Draft

denik wants to merge 5 commits into
denik/null-merging-testsfrom
denik/null-merging

Conversation

@denik

@denik denik commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Changes

A null now removes the value it overrides; previously every such null was ignored (recorded in #7260, which this is stacked on).

  • Target: targets.<t>.<...>: null removes the value from the configuration when the target is selected: a resource (resources.jobs.foo: null leaves foo out of that target), a field, a block, a map entry (tags.x), a list, and the top-level fields a target replaces (mode, cluster_id, run_as, variable default/lookup).
  • Keyed lists: in tasks, job_clusters, job parameters and pipeline clusters, a null field of an element removes that field from the element with the same key, e.g. - task_key: t1 with max_retries: null.
  • Include: a null in an included file removes the value from databricks.yml and earlier includes, including a whole resource or section. Target overrides split across includes compose in file order: a later null beats an earlier value and a later value beats an earlier null.
  • Nothing to remove: a null adds nothing, without the expected a ... value, found null warning. This also holds for nulls in databricks.yml outside targets, so an empty run_as: no longer errors, and resources: null / schedule: null are fine. An empty named entry (targets.<name>:, variables.<name>:, resources.<type>.<name>:, artifacts.<name>:, scripts.<name>:) in a file still declares the entry, so empty targets and variables keep working and empty resources, artifacts and scripts are still reported.

Nulls don't survive the typed round trip that runs around every mutator, and a null scalar doesn't convert to the typed config at all. So Root keeps the target sections with their nulls on the side (withNulls) and puts them back into the target when it is merged. A keyed list that holds nulls is merged by key with the root's list at that point, because MergeJobTasks and friends run later, when the nulls are gone. New in libs/dyn: merge.MergeKeepingNulls, merge.MergeRemovingNulls, merge.ElementsByKeyKeepingNulls, dyn.DropNulls and the convert.KeepNulls normalize option.

Why

To leave a resource out of one target, or undo a field set at the base level, without restructuring the configuration.

Tests

The tests from #7260 now show the removals. Existing goldens that change: run_as/empty_override (an empty run_as: in a target now removes run_as), validate/empty_tasks and validate/required (a null tasks / run_job_task is dropped), and validate/presets_name_prefix_dev and deploy/mlops-stacks (no null warning). Unit tests for the new merge modes and DropNulls.

This pull request and its description were written by Isaac.

denik and others added 2 commits October 30, 2026 15:14
A null in an included file removes the value it lands on from
databricks.yml and earlier includes, also a whole resource or section.
A null in a target removes the value from the configuration when the
target is selected: a resource, a field, a map entry, a list, and a
field of a task, job cluster, job parameter or pipeline cluster matched
by its key. A null that has nothing to remove adds nothing, without a
warning; an empty targets.<name> or variables.<name> still declares the
target or variable.

Nulls do not survive the typed round trip between mutators, so the
nulls of the target sections are kept on the side until the target is
merged.

Co-authored-by: Isaac <no-reply@databricks.com>
… change

Co-authored-by: Isaac <no-reply@databricks.com>
@denik
denik added this pull request to stack #7262 October 30, 2026 14:15
denik and others added 2 commits October 30, 2026 15:15
Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
@github-actions github-actions Bot added the DABs DABs related issues label Oct 30, 2026
@denik denik changed the title denik/null merging Make a null in an include or a target remove the value it overrides Oct 30, 2026
@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Commit: b7e451e19 | Workflow run

Regression test report

Selected 14 changed tests (limit=20, 0 not selected)

28 tests: regression=28 unreleased=0 coverage=0 failing=0

test branch main (e9e2d63) latest (v1.23.0)
TestAccept/bundle/deploy/mlops-stacks/DMS= ✅ ❌ ❌
TestAccept/bundle/deploy/mlops-stacks/DMS=true ✅ ❌ ❌
TestAccept/bundle/run_as/empty_override/DMS= ✅ ❌ ❌
TestAccept/bundle/run_as/empty_override/DMS=true ✅ ❌ ❌
TestAccept/bundle/validate/empty_tasks/DMS= ✅ ❌ ❌
TestAccept/bundle/validate/empty_tasks/DMS=true ✅ ❌ ❌
TestAccept/bundle/validate/nulls/include_removes/DMS= ✅ ❌ ❌
TestAccept/bundle/validate/nulls/include_removes/DMS=true ✅ ❌ ❌
TestAccept/bundle/validate/nulls/include_target_overrides/DMS= ✅ ❌ ❌
TestAccept/bundle/validate/nulls/include_target_overrides/DMS=true ✅ ❌ ❌
TestAccept/bundle/validate/nulls/resources_container/DMS= ✅ ❌ ❌
TestAccept/bundle/validate/nulls/resources_container/DMS=true ✅ ❌ ❌
TestAccept/bundle/validate/nulls/root_without_base/DMS= ✅ ❌ ❌
TestAccept/bundle/validate/nulls/root_without_base/DMS=true ✅ ❌ ❌
TestAccept/bundle/validate/nulls/schedule_default_materialization/DMS= ✅ ❌ ❌
TestAccept/bundle/validate/nulls/schedule_default_materialization/DMS=true ✅ ❌ ❌
TestAccept/bundle/validate/nulls/target_keyed_slices/DMS= ✅ ❌ ❌
TestAccept/bundle/validate/nulls/target_keyed_slices/DMS=true ✅ ❌ ❌
TestAccept/bundle/validate/nulls/target_removes_job_fields/DMS= ✅ ❌ ❌
TestAccept/bundle/validate/nulls/target_removes_job_fields/DMS=true ✅ ❌ ❌
TestAccept/bundle/validate/nulls/target_removes_resource/DMS= ✅ ❌ ❌
TestAccept/bundle/validate/nulls/target_removes_resource/DMS=true ✅ ❌ ❌
TestAccept/bundle/validate/nulls/target_removes_top_level_fields/DMS= ✅ ❌ ❌
TestAccept/bundle/validate/nulls/target_removes_top_level_fields/DMS=true ✅ ❌ ❌
TestAccept/bundle/validate/presets_name_prefix_dev/DMS= ✅ ❌ ❌
TestAccept/bundle/validate/presets_name_prefix_dev/DMS=true ✅ ❌ ❌
TestAccept/bundle/validate/required/DMS= ✅ ❌ ❌
TestAccept/bundle/validate/required/DMS=true ✅ ❌ ❌
TestAccept/bundle/deploy/mlops-stacks/DMS=: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌

main (e9e2d63):

acceptance_test.go:1341: Diff:
        --- bundle/deploy/mlops-stacks/output.txt
        +++ /tmp/TestAcceptbundledeploymlops-stacksDMS=1796796550/002/output.txt
        @@ -25,6 +25,10 @@
         [Databricks MLOps Stacks](https://github.com/databricks/mlops-stacks),
         
         >>> [CLI] bundle summary --var catalog_name=main
        +Warning: expected a string value, found null
        +  at targets.dev.workspace.host
        +  in databricks.yml:37:12
        +
         Warning: unknown field: description
           at resources.experiments.experiment
           in resources/ml-artifacts-resource.yml:28:7
        @@ -52,6 +56,10 @@
               URL:  (not deployed)
         
         >>> [CLI] bundle validate --var catalog_name=main
        +Warning: expected a string value, found null
        +  at targets.dev.workspace.host
        +  in databricks.yml:37:12
        +
         Warning: unknown field: description
           at resources.experiments.experiment
           in resources/ml-artifacts-resource.yml:28:7
        @@ -62,9 +70,13 @@
           User: [USERNAME]
           Path: /Workspace/Users/[USERNAME]/.bundle/project_name_[UNIQUE_NAME]/dev
         
        -Found 1 warning
        +Found 2 warnings
         
         >>> [CLI] bundle deploy --var catalog_name=main
        +Warning: expected a string value, found null
        +  at targets.dev.workspace.host
        +  in databricks.yml:37:12
        +
         Warning: unknown field: description
           at resources.experiments.experiment
           in resources/ml-artifacts-resource.yml:28:7
        @@ -82,6 +92,10 @@
         Resources: 8 created, 0 changed, 0 deleted, 0 unchanged
         
         >>> [CLI] bundle summary --var catalog_name=main -o json
        +Warning: expected a string value, found null
        +  at targets.dev.workspace.host
        +  in databricks.yml:37:12
        +
         Warning: unknown field: description
           at resources.experiments.experiment
           in resources/ml-artifacts-resource.yml:28:7
        @@ -94,10 +108,18 @@
         }
         
         === Assert the batch inference job actually exists
        +Warning: expected a string value, found null
        +  at targets.dev.workspace.host
        +  in databricks.yml:37:12
        +
         Warning: unknown field: description
           at resources.experiments.experiment
           in resources/ml-artifacts-resource.yml:28:7
         
        +Warning: expected a string value, found null
        +  at targets.dev.workspace.host
        +  in databricks.yml:37:12
        +
         Warning: unknown field: description
           at resources.experiments.experiment
           in resources/ml-artifacts-resource.yml:28:7
        @@ -107,6 +125,10 @@
         }
         
         >>> [CLI] bundle destroy --var catalog_name=main --auto-approve
        +Warning: expected a string value, found null
        +  at targets.dev.workspace.host
        +  in databricks.yml:37:12
        +
         Warning: unknown field: description
           at resources.experiments.experiment
           in resources/ml-artifacts-resource.yml:28:7
        @@ -122,6 +144,10 @@
         Destroy: 4 deleted
         
         >>> [CLI] schemas delete main.project_name_[UNIQUE_NAME]
        +Warning: expected a string value, found null
        +  at targets.dev.workspace.host
        +  in databricks.yml:37:12
        +
         Warning: unknown field: description
           at resources.experiments.experiment
           in resources/ml-artifacts-resource.yml:28:7

latest (v1.23.0): same output as main (e9e2d63)

TestAccept/bundle/deploy/mlops-stacks/DMS=true: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌

main (e9e2d63):

acceptance_test.go:1341: Diff:
        --- bundle/deploy/mlops-stacks/output.txt
        +++ /tmp/TestAcceptbundledeploymlops-stacksDMS=true2694353843/002/output.txt
        @@ -25,6 +25,10 @@
         [Databricks MLOps Stacks](https://github.com/databricks/mlops-stacks),
         
         >>> [CLI] bundle summary --var catalog_name=main
        +Warning: expected a string value, found null
        +  at targets.dev.workspace.host
        +  in databricks.yml:37:12
        +
         Warning: unknown field: description
           at resources.experiments.experiment
           in resources/ml-artifacts-resource.yml:28:7
        @@ -52,6 +56,10 @@
               URL:  (not deployed)
         
         >>> [CLI] bundle validate --var catalog_name=main
        +Warning: expected a string value, found null
        +  at targets.dev.workspace.host
        +  in databricks.yml:37:12
        +
         Warning: unknown field: description
           at resources.experiments.experiment
           in resources/ml-artifacts-resource.yml:28:7
        @@ -62,9 +70,13 @@
           User: [USERNAME]
           Path: /Workspace/Users/[USERNAME]/.bundle/project_name_[UNIQUE_NAME]/dev
         
        -Found 1 warning
        +Found 2 warnings
         
         >>> [CLI] bundle deploy --var catalog_name=main
        +Warning: expected a string value, found null
        +  at targets.dev.workspace.host
        +  in databricks.yml:37:12
        +
         Warning: unknown field: description
           at resources.experiments.experiment
           in resources/ml-artifacts-resource.yml:28:7
        @@ -82,6 +92,10 @@
         Resources: 8 created, 0 changed, 0 deleted, 0 unchanged
         
         >>> [CLI] bundle summary --var catalog_name=main -o json
        +Warning: expected a string value, found null
        +  at targets.dev.workspace.host
        +  in databricks.yml:37:12
        +
         Warning: unknown field: description
           at resources.experiments.experiment
           in resources/ml-artifacts-resource.yml:28:7
        @@ -94,10 +108,18 @@
         }
         
         === Assert the batch inference job actually exists
        +Warning: expected a string value, found null
        +  at targets.dev.workspace.host
        +  in databricks.yml:37:12
        +
         Warning: unknown field: description
           at resources.experiments.experiment
           in resources/ml-artifacts-resource.yml:28:7
         
        +Warning: expected a string value, found null
        +  at targets.dev.workspace.host
        +  in databricks.yml:37:12
        +
         Warning: unknown field: description
           at resources.experiments.experiment
           in resources/ml-artifacts-resource.yml:28:7
        @@ -107,6 +125,10 @@
         }
         
         >>> [CLI] bundle destroy --var catalog_name=main --auto-approve
        +Warning: expected a string value, found null
        +  at targets.dev.workspace.host
        +  in databricks.yml:37:12
        +
         Warning: unknown field: description
           at resources.experiments.experiment
           in resources/ml-artifacts-resource.yml:28:7
        @@ -122,6 +144,10 @@
         Destroy: 4 deleted
         
         >>> [CLI] schemas delete main.project_name_[UNIQUE_NAME]
        +Warning: expected a string value, found null
        +  at targets.dev.workspace.host
        +  in databricks.yml:37:12
        +
         Warning: unknown field: description
           at resources.experiments.experiment
           in resources/ml-artifacts-resource.yml:28:7

latest (v1.23.0): same output as main (e9e2d63)

TestAccept/bundle/run_as/empty_override/DMS=: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌

main (e9e2d63):

acceptance_test.go:1341: 
        	Error Trace:	/home/runner/work/cli/cli/libs/testdiff/testdiff.go:22
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1341
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1082
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:659
        	Error:      	Not equal: 
        	            	expected: "\n>>> [CLI] bundle validate -o json\n{\n  \"run_as\": null,\n  \"job_run_as\": null\n}\n"
        	            	actual  : "\n>>> [CLI] bundle validate -o json\n{\n  \"run_as\": {\n    \"user_name\": \"my_user_name\"\n  },\n  \"job_run_as\": {\n    \"user_name\": \"my_user_name\"\n  }\n}\n"
        	            	
        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -3,4 +3,8 @@
        	            	 {
        	            	-  "run_as": null,
        	            	-  "job_run_as": null
        	            	+  "run_as": {
        	            	+    "user_name": "my_user_name"
        	            	+  },
        	            	+  "job_run_as": {
        	            	+    "user_name": "my_user_name"
        	            	+  }
        	            	 }
        	Test:       	TestAccept/bundle/run_as/empty_override/DMS=
        	Messages:   	bundle/run_as/empty_override/output.txt vs /tmp/TestAcceptbundlerun_asempty_overrideDMS=2159616302/002/output.txt

latest (v1.23.0): same output as main (e9e2d63)

TestAccept/bundle/run_as/empty_override/DMS=true: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌

main (e9e2d63):

acceptance_test.go:1341: 
        	Error Trace:	/home/runner/work/cli/cli/libs/testdiff/testdiff.go:22
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1341
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1082
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:659
        	Error:      	Not equal: 
        	            	expected: "\n>>> [CLI] bundle validate -o json\n{\n  \"run_as\": null,\n  \"job_run_as\": null\n}\n"
        	            	actual  : "\n>>> [CLI] bundle validate -o json\n{\n  \"run_as\": {\n    \"user_name\": \"my_user_name\"\n  },\n  \"job_run_as\": {\n    \"user_name\": \"my_user_name\"\n  }\n}\n"
        	            	
        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -3,4 +3,8 @@
        	            	 {
        	            	-  "run_as": null,
        	            	-  "job_run_as": null
        	            	+  "run_as": {
        	            	+    "user_name": "my_user_name"
        	            	+  },
        	            	+  "job_run_as": {
        	            	+    "user_name": "my_user_name"
        	            	+  }
        	            	 }
        	Test:       	TestAccept/bundle/run_as/empty_override/DMS=true
        	Messages:   	bundle/run_as/empty_override/output.txt vs /tmp/TestAcceptbundlerun_asempty_overrideDMS=true2443246341/002/output.txt

latest (v1.23.0):

acceptance_test.go:1341: 
        	Error Trace:	/home/runner/work/cli/cli/libs/testdiff/testdiff.go:22
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1341
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1082
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:659
        	Error:      	Not equal: 
        	            	expected: "\n>>> [CLI] bundle validate -o json\n{\n  \"run_as\": null,\n  \"job_run_as\": null\n}\n"
        	            	actual  : "\n>>> [CLI] bundle validate -o json\n{\n  \"run_as\": {\n    \"user_name\": \"my_user_name\"\n  },\n  \"job_run_as\": {\n    \"user_name\": \"my_user_name\"\n  }\n}\n"
        	            	
        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -3,4 +3,8 @@
        	            	 {
        	            	-  "run_as": null,
        	            	-  "job_run_as": null
        	            	+  "run_as": {
        	            	+    "user_name": "my_user_name"
        	            	+  },
        	            	+  "job_run_as": {
        	            	+    "user_name": "my_user_name"
        	            	+  }
        	            	 }
        	Test:       	TestAccept/bundle/run_as/empty_override/DMS=true
        	Messages:   	bundle/run_as/empty_override/output.txt vs /tmp/TestAcceptbundlerun_asempty_overrideDMS=true2311413421/002/output.txt
FAIL
TestAccept/bundle/validate/empty_tasks/DMS=: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌

main (e9e2d63):

acceptance_test.go:1341: 
        	Error Trace:	/home/runner/work/cli/cli/libs/testdiff/testdiff.go:22
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1341
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1082
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:659
        	Error:      	Not equal: 
        	            	expected: "\n>>> [CLI] bundle validate -o json\n{\n  \"empty_tasks\": {\n    \"deployment\": {\n      \"kind\": \"BUNDLE\",\n      \"metadata_file_path\": \"/Workspace/Users/[USERNAME]/.bundle/empty_tasks/default/state/metadata.json\"\n    },\n    \"edit_mode\": \"UI_LOCKED\",\n    \"format\": \"MULTI_TASK\",\n    \"max_concurrent_runs\": 1,\n    \"name\": \"job with empty tasks\",\n    \"queue\": {\n      \"enabled\": true\n    }\n  },\n  \"valid\": {\n    \"deployment\": {\n      \"kind\": \"BUNDLE\",\n      \"metadata_file_path\": \"/Workspace/Users/[USERNAME]/.bundle/empty_tasks/default/state/metadata.json\"\n    },\n    \"edit_mode\": \"UI_LOCKED\",\n    \"format\": \"MULTI_TASK\",\n    \"max_concurrent_runs\": 1,\n    \"name\": \"valid job\",\n    \"queue\": {\n      \"enabled\": true\n    },\n    \"tasks\": [\n      {\n        \"sql_task\": {\n          \"query\": {\n            \"query_id\": \"abc\"\n          },\n          \"warehouse_id\": \"w123\"\n        },\n        \"task_key\": \"t\"\n      }\n    ]\n  }\n}\n"
        	            	actual  : "\n>>> [CLI] bundle validate -o json\n{\n  \"empty_tasks\": {\n    \"deployment\": {\n      \"kind\": \"BUNDLE\",\n      \"metadata_file_path\": \"/Workspace/Users/[USERNAME]/.bundle/empty_tasks/default/state/metadata.json\"\n    },\n    \"edit_mode\": \"UI_LOCKED\",\n    \"format\": \"MULTI_TASK\",\n    \"max_concurrent_runs\": 1,\n    \"name\": \"job with empty tasks\",\n    \"queue\": {\n      \"enabled\": true\n    },\n    \"tasks\": null\n  },\n  \"valid\": {\n    \"deployment\": {\n      \"kind\": \"BUNDLE\",\n      \"metadata_file_path\": \"/Workspace/Users/[USERNAME]/.bundle/empty_tasks/default/state/metadata.json\"\n    },\n    \"edit_mode\": \"UI_LOCKED\",\n    \"format\": \"MULTI_TASK\",\n    \"max_concurrent_runs\": 1,\n    \"name\": \"valid job\",\n    \"queue\": {\n      \"enabled\": true\n    },\n    \"tasks\": [\n      {\n        \"sql_task\": {\n          \"query\": {\n            \"query_id\": \"abc\"\n          },\n          \"warehouse_id\": \"w123\"\n        },\n        \"task_key\": \"t\"\n      }\n    ]\n  }\n}\n"
        	            	
        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -14,3 +14,4 @@
        	            	       "enabled": true
        	            	-    }
        	            	+    },
        	            	+    "tasks": null
        	            	   },
        	Test:       	TestAccept/bundle/validate/empty_tasks/DMS=
        	Messages:   	bundle/validate/empty_tasks/output.txt vs /tmp/TestAcceptbundlevalidateempty_tasksDMS=3128364653/002/output.txt

latest (v1.23.0): same output as main (e9e2d63)

TestAccept/bundle/validate/empty_tasks/DMS=true: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌

main (e9e2d63):

acceptance_test.go:1341: 
        	Error Trace:	/home/runner/work/cli/cli/libs/testdiff/testdiff.go:22
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1341
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1082
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:659
        	Error:      	Not equal: 
        	            	expected: "\n>>> [CLI] bundle validate -o json\n{\n  \"empty_tasks\": {\n    \"deployment\": {\n      \"kind\": \"BUNDLE\",\n      \"metadata_file_path\": \"/Workspace/Users/[USERNAME]/.bundle/empty_tasks/default/state/metadata.json\"\n    },\n    \"edit_mode\": \"UI_LOCKED\",\n    \"format\": \"MULTI_TASK\",\n    \"max_concurrent_runs\": 1,\n    \"name\": \"job with empty tasks\",\n    \"queue\": {\n      \"enabled\": true\n    }\n  },\n  \"valid\": {\n    \"deployment\": {\n      \"kind\": \"BUNDLE\",\n      \"metadata_file_path\": \"/Workspace/Users/[USERNAME]/.bundle/empty_tasks/default/state/metadata.json\"\n    },\n    \"edit_mode\": \"UI_LOCKED\",\n    \"format\": \"MULTI_TASK\",\n    \"max_concurrent_runs\": 1,\n    \"name\": \"valid job\",\n    \"queue\": {\n      \"enabled\": true\n    },\n    \"tasks\": [\n      {\n        \"sql_task\": {\n          \"query\": {\n            \"query_id\": \"abc\"\n          },\n          \"warehouse_id\": \"w123\"\n        },\n        \"task_key\": \"t\"\n      }\n    ]\n  }\n}\n"
        	            	actual  : "\n>>> [CLI] bundle validate -o json\n{\n  \"empty_tasks\": {\n    \"deployment\": {\n      \"kind\": \"BUNDLE\",\n      \"metadata_file_path\": \"/Workspace/Users/[USERNAME]/.bundle/empty_tasks/default/state/metadata.json\"\n    },\n    \"edit_mode\": \"UI_LOCKED\",\n    \"format\": \"MULTI_TASK\",\n    \"max_concurrent_runs\": 1,\n    \"name\": \"job with empty tasks\",\n    \"queue\": {\n      \"enabled\": true\n    },\n    \"tasks\": null\n  },\n  \"valid\": {\n    \"deployment\": {\n      \"kind\": \"BUNDLE\",\n      \"metadata_file_path\": \"/Workspace/Users/[USERNAME]/.bundle/empty_tasks/default/state/metadata.json\"\n    },\n    \"edit_mode\": \"UI_LOCKED\",\n    \"format\": \"MULTI_TASK\",\n    \"max_concurrent_runs\": 1,\n    \"name\": \"valid job\",\n    \"queue\": {\n      \"enabled\": true\n    },\n    \"tasks\": [\n      {\n        \"sql_task\": {\n          \"query\": {\n            \"query_id\": \"abc\"\n          },\n          \"warehouse_id\": \"w123\"\n        },\n        \"task_key\": \"t\"\n      }\n    ]\n  }\n}\n"
        	            	
        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -14,3 +14,4 @@
        	            	       "enabled": true
        	            	-    }
        	            	+    },
        	            	+    "tasks": null
        	            	   },
        	Test:       	TestAccept/bundle/validate/empty_tasks/DMS=true
        	Messages:   	bundle/validate/empty_tasks/output.txt vs /tmp/TestAcceptbundlevalidateempty_tasksDMS=true1171968932/002/output.txt

latest (v1.23.0): same output as main (e9e2d63)

TestAccept/bundle/validate/nulls/include_removes/DMS=: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌

main (e9e2d63):

acceptance_test.go:1341: Diff:
        --- bundle/validate/nulls/include_removes/output.txt
        +++ /tmp/TestAcceptbundlevalidatenullsinclude_removesDMS=3460133596/002/output.txt
        @@ -1,28 +1,58 @@
         
         >>> [CLI] bundle validate -o json
        -Error: no value assigned to required variable with_default. Variables are usually assigned in databricks.yml, and they can be overridden using "--var", the BUNDLE_VAR_with_default environment variable, or .databricks/bundle/<target>/variable-overrides.json
        +Warning: expected a string value, found null
        +  at bundle.cluster_id
        +  in override.yml:2:15
         
        +Warning: expected a string value, found null
        +  at presets.name_prefix
        +  in override.yml:5:16
         
        +Warning: expected a string value, found null
        +  at presets.tags.removed
        +  in override.yml:7:14
        +
        +Warning: expected a string value, found null
        +  at presets.tags.not_in_base
        +  in override.yml:8:18
        +
        +Error: multiple resources or scripts have been defined with the same key: bar
        +  at resources.jobs.bar
        +  in databricks.yml:34:7
        +     override.yml:23:10
        +
        +
         Exit code: 1
         {
        -  "cluster_id": null,
        +  "cluster_id": "base-cluster",
           "presets": {
        -    "name_prefix": null,
        +    "name_prefix": "base-",
             "tags": {
        -      "kept": "1"
        +      "kept": "1",
        +      "removed": "1"
             }
           },
           "sync": {
        -    "paths": [
        -      "."
        +    "include": [
        +      "databricks.yml"
             ]
           },
        -  "permissions": null,
        +  "permissions": [
        +    {
        +      "group_name": "users",
        +      "level": "CAN_VIEW"
        +    }
        +  ],
           "variables": {
        -    "with_default": {}
        +    "with_default": {
        +      "default": "base"
        +    }
           },
        -  "run_as": null,
        +  "run_as": {
        +    "user_name": "base@example.com"
        +  },
           "jobs": [
        +    "bar",
             "foo"
           ]
         }

latest (v1.23.0): same output as main (e9e2d63)

TestAccept/bundle/validate/nulls/include_removes/DMS=true: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌

main (e9e2d63):

acceptance_test.go:1341: Diff:
        --- bundle/validate/nulls/include_removes/output.txt
        +++ /tmp/TestAcceptbundlevalidatenullsinclude_removesDMS=true1361910128/002/output.txt
        @@ -1,28 +1,58 @@
         
         >>> [CLI] bundle validate -o json
        -Error: no value assigned to required variable with_default. Variables are usually assigned in databricks.yml, and they can be overridden using "--var", the BUNDLE_VAR_with_default environment variable, or .databricks/bundle/<target>/variable-overrides.json
        +Warning: expected a string value, found null
        +  at bundle.cluster_id
        +  in override.yml:2:15
         
        +Warning: expected a string value, found null
        +  at presets.name_prefix
        +  in override.yml:5:16
         
        +Warning: expected a string value, found null
        +  at presets.tags.removed
        +  in override.yml:7:14
        +
        +Warning: expected a string value, found null
        +  at presets.tags.not_in_base
        +  in override.yml:8:18
        +
        +Error: multiple resources or scripts have been defined with the same key: bar
        +  at resources.jobs.bar
        +  in databricks.yml:34:7
        +     override.yml:23:10
        +
        +
         Exit code: 1
         {
        -  "cluster_id": null,
        +  "cluster_id": "base-cluster",
           "presets": {
        -    "name_prefix": null,
        +    "name_prefix": "base-",
             "tags": {
        -      "kept": "1"
        +      "kept": "1",
        +      "removed": "1"
             }
           },
           "sync": {
        -    "paths": [
        -      "."
        +    "include": [
        +      "databricks.yml"
             ]
           },
        -  "permissions": null,
        +  "permissions": [
        +    {
        +      "group_name": "users",
        +      "level": "CAN_VIEW"
        +    }
        +  ],
           "variables": {
        -    "with_default": {}
        +    "with_default": {
        +      "default": "base"
        +    }
           },
        -  "run_as": null,
        +  "run_as": {
        +    "user_name": "base@example.com"
        +  },
           "jobs": [
        +    "bar",
             "foo"
           ]
         }
        
FAIL

latest (v1.23.0):

acceptance_test.go:1341: Diff:
        --- bundle/validate/nulls/include_removes/output.txt
        +++ /tmp/TestAcceptbundlevalidatenullsinclude_removesDMS=true2617036871/002/output.txt
        @@ -1,28 +1,58 @@
         
         >>> [CLI] bundle validate -o json
        -Error: no value assigned to required variable with_default. Variables are usually assigned in databricks.yml, and they can be overridden using "--var", the BUNDLE_VAR_with_default environment variable, or .databricks/bundle/<target>/variable-overrides.json
        +Warning: expected a string value, found null
        +  at bundle.cluster_id
        +  in override.yml:2:15
         
        +Warning: expected a string value, found null
        +  at presets.name_prefix
        +  in override.yml:5:16
         
        +Warning: expected a string value, found null
        +  at presets.tags.removed
        +  in override.yml:7:14
        +
        +Warning: expected a string value, found null
        +  at presets.tags.not_in_base
        +  in override.yml:8:18
        +
        +Error: multiple resources or scripts have been defined with the same key: bar
        +  at resources.jobs.bar
        +  in databricks.yml:34:7
        +     override.yml:23:10
        +
        +
         Exit code: 1
         {
        -  "cluster_id": null,
        +  "cluster_id": "base-cluster",
           "presets": {
        -    "name_prefix": null,
        +    "name_prefix": "base-",
             "tags": {
        -      "kept": "1"
        +      "kept": "1",
        +      "removed": "1"
             }
           },
           "sync": {
        -    "paths": [
        -      "."
        +    "include": [
        +      "databricks.yml"
             ]
           },
        -  "permissions": null,
        +  "permissions": [
        +    {
        +      "group_name": "users",
        +      "level": "CAN_VIEW"
        +    }
        +  ],
           "variables": {
        -    "with_default": {}
        +    "with_default": {
        +      "default": "base"
        +    }
           },
        -  "run_as": null,
        +  "run_as": {
        +    "user_name": "base@example.com"
        +  },
           "jobs": [
        +    "bar",
             "foo"
           ]
         }
TestAccept/bundle/validate/nulls/include_target_overrides/DMS=: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌

main (e9e2d63):

acceptance_test.go:1341: 
        	Error Trace:	/home/runner/work/cli/cli/libs/testdiff/testdiff.go:22
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1341
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1082
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:659
        	Error:      	Not equal: 
        	            	expected: "\n>>> [CLI] bundle validate -o json -t dev\n{\n  \"foo\": {\n    \"description\": \"description from b.yml\",\n    \"max_concurrent_runs\": 1,\n    \"timeout_seconds\": null,\n    \"tags\": {\n      \"kept\": \"1\"\n    },\n    \"tasks\": [\n      {\n        \"task_key\": \"t1\",\n        \"max_retries\": null\n      }\n    ]\n  },\n  \"jobs\": [\n    \"foo\"\n  ]\n}\n"
        	            	actual  : "\n>>> [CLI] bundle validate -o json -t dev\nWarning: expected a string value, found null\n  at targets.dev.resources.jobs.foo.description\n  in a.yml:7:24\n\nWarning: expected a string value, found null\n  at targets.dev.resources.jobs.foo.tags.removed\n  in a.yml:10:22\n\nWarning: expected a int value, found null\n  at targets.dev.resources.jobs.foo.tasks[0].max_retries\n  in a.yml:13:28\n\nWarning: expected a int value, found null\n  at targets.dev.resources.jobs.foo.max_concurrent_runs\n  in b.yml:8:32\n\nWarning: expected a int value, found null\n  at targets.dev.resources.jobs.foo.timeout_seconds\n  in b.yml:9:28\n\n{\n  \"foo\": {\n    \"description\": \"description from b.yml\",\n    \"max_concurrent_runs\": 10,\n    \"timeout_seconds\": 120,\n    \"tags\": {\n      \"kept\": \"1\",\n      \"removed\": \"1\"\n    },\n    \"tasks\": [\n      {\n        \"task_key\": \"t1\",\n        \"max_retries\": 3\n      }\n    ]\n  },\n  \"jobs\": [\n    \"bar\",\n    \"foo\"\n  ]\n}\n"
        	            	
        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -2,2 +2,22 @@
        	            	 >>> [CLI] bundle validate -o json -t dev
        	            	+Warning: expected a string value, found null
        	            	+  at targets.dev.resources.jobs.foo.description
        	            	+  in a.yml:7:24
        	            	+
        	            	+Warning: expected a string value, found null
        	            	+  at targets.dev.resources.jobs.foo.tags.removed
        	            	+  in a.yml:10:22
        	            	+
        	            	+Warning: expected a int value, found null
        	            	+  at targets.dev.resources.jobs.foo.tasks[0].max_retries
        	            	+  in a.yml:13:28
        	            	+
        	            	+Warning: expected a int value, found null
        	            	+  at targets.dev.resources.jobs.foo.max_concurrent_runs
        	            	+  in b.yml:8:32
        	            	+
        	            	+Warning: expected a int value, found null
        	            	+  at targets.dev.resources.jobs.foo.timeout_seconds
        	            	+  in b.yml:9:28
        	            	+
        	            	 {
        	            	@@ -5,6 +25,7 @@
        	            	     "description": "description from b.yml",
        	            	-    "max_concurrent_runs": 1,
        	            	-    "timeout_seconds": null,
        	            	+    "max_concurrent_runs": 10,
        	            	+    "timeout_seconds": 120,
        	            	     "tags": {
        	            	-      "kept": "1"
        	            	+      "kept": "1",
        	            	+      "removed": "1"
        	            	     },
        	            	@@ -13,3 +34,3 @@
        	            	         "task_key": "t1",
        	            	-        "max_retries": null
        	            	+        "max_retries": 3
        	            	       }
        	            	@@ -18,2 +39,3 @@
        	            	   "jobs": [
        	            	+    "bar",
        	            	     "foo"
        	Test:       	TestAccept/bundle/validate/nulls/include_target_overrides/DMS=
        	Messages:   	bundle/validate/nulls/include_target_overrides/output.txt vs /tmp/TestAcceptbundlevalidatenullsinclude_target_overridesDMS=646929281/002/output.txt

latest (v1.23.0): same output as main (e9e2d63)

TestAccept/bundle/validate/nulls/include_target_overrides/DMS=true: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌

main (e9e2d63):

acceptance_test.go:1341: 
        	Error Trace:	/home/runner/work/cli/cli/libs/testdiff/testdiff.go:22
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1341
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1082
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:659
        	Error:      	Not equal: 
        	            	expected: "\n>>> [CLI] bundle validate -o json -t dev\n{\n  \"foo\": {\n    \"description\": \"description from b.yml\",\n    \"max_concurrent_runs\": 1,\n    \"timeout_seconds\": null,\n    \"tags\": {\n      \"kept\": \"1\"\n    },\n    \"tasks\": [\n      {\n        \"task_key\": \"t1\",\n        \"max_retries\": null\n      }\n    ]\n  },\n  \"jobs\": [\n    \"foo\"\n  ]\n}\n"
        	            	actual  : "\n>>> [CLI] bundle validate -o json -t dev\nWarning: expected a string value, found null\n  at targets.dev.resources.jobs.foo.description\n  in a.yml:7:24\n\nWarning: expected a string value, found null\n  at targets.dev.resources.jobs.foo.tags.removed\n  in a.yml:10:22\n\nWarning: expected a int value, found null\n  at targets.dev.resources.jobs.foo.tasks[0].max_retries\n  in a.yml:13:28\n\nWarning: expected a int value, found null\n  at targets.dev.resources.jobs.foo.max_concurrent_runs\n  in b.yml:8:32\n\nWarning: expected a int value, found null\n  at targets.dev.resources.jobs.foo.timeout_seconds\n  in b.yml:9:28\n\n{\n  \"foo\": {\n    \"description\": \"description from b.yml\",\n    \"max_concurrent_runs\": 10,\n    \"timeout_seconds\": 120,\n    \"tags\": {\n      \"kept\": \"1\",\n      \"removed\": \"1\"\n    },\n    \"tasks\": [\n      {\n        \"task_key\": \"t1\",\n        \"max_retries\": 3\n      }\n    ]\n  },\n  \"jobs\": [\n    \"bar\",\n    \"foo\"\n  ]\n}\n"
        	            	
        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -2,2 +2,22 @@
        	            	 >>> [CLI] bundle validate -o json -t dev
        	            	+Warning: expected a string value, found null
        	            	+  at targets.dev.resources.jobs.foo.description
        	            	+  in a.yml:7:24
        	            	+
        	            	+Warning: expected a string value, found null
        	            	+  at targets.dev.resources.jobs.foo.tags.removed
        	            	+  in a.yml:10:22
        	            	+
        	            	+Warning: expected a int value, found null
        	            	+  at targets.dev.resources.jobs.foo.tasks[0].max_retries
        	            	+  in a.yml:13:28
        	            	+
        	            	+Warning: expected a int value, found null
        	            	+  at targets.dev.resources.jobs.foo.max_concurrent_runs
        	            	+  in b.yml:8:32
        	            	+
        	            	+Warning: expected a int value, found null
        	            	+  at targets.dev.resources.jobs.foo.timeout_seconds
        	            	+  in b.yml:9:28
        	            	+
        	            	 {
        	            	@@ -5,6 +25,7 @@
        	            	     "description": "description from b.yml",
        	            	-    "max_concurrent_runs": 1,
        	            	-    "timeout_seconds": null,
        	            	+    "max_concurrent_runs": 10,
        	            	+    "timeout_seconds": 120,
        	            	     "tags": {
        	            	-      "kept": "1"
        	            	+      "kept": "1",
        	            	+      "removed": "1"
        	            	     },
        	            	@@ -13,3 +34,3 @@
        	            	         "task_key": "t1",
        	            	-        "max_retries": null
        	            	+        "max_retries": 3
        	            	       }
        	            	@@ -18,2 +39,3 @@
        	            	   "jobs": [
        	            	+    "bar",
        	            	     "foo"
        	Test:       	TestAccept/bundle/validate/nulls/include_target_overrides/DMS=true
        	Messages:   	bundle/validate/nulls/include_target_overrides/output.txt vs /tmp/TestAcceptbundlevalidatenullsinclude_target_overridesDMS=tr2687187848/002/output.txt

latest (v1.23.0): same output as main (e9e2d63)

TestAccept/bundle/validate/nulls/resources_container/DMS=: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌

main (e9e2d63):

acceptance_test.go:1341: 
        	Error Trace:	/home/runner/work/cli/cli/libs/testdiff/testdiff.go:22
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1341
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1082
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:659
        	Error:      	Not equal: 
        	            	expected: "\n>>> [CLI] bundle validate\nName: test-bundle\nTarget: default\nWorkspace:\n  User: [USERNAME]\n  Path: /Workspace/Users/[USERNAME]/.bundle/test-bundle/default\n\nValidation OK!\n"
        	            	actual  : "\n>>> [CLI] bundle validate\nError: expected a map at \"resources\", found nil\n\nName: test-bundle\n\nFound 1 error\n\nExit code: 1\n"
        	            	
        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -2,9 +2,9 @@
        	            	 >>> [CLI] bundle validate
        	            	+Error: expected a map at "resources", found nil
        	            	+
        	            	 Name: test-bundle
        	            	-Target: default
        	            	-Workspace:
        	            	-  User: [USERNAME]
        	            	-  Path: /Workspace/Users/[USERNAME]/.bundle/test-bundle/default
        	            	 
        	            	-Validation OK!
        	            	+Found 1 error
        	            	 
        	            	+Exit code: 1
        	            	+
        	Test:       	TestAccept/bundle/validate/nulls/resources_container/DMS=
        	Messages:   	bundle/validate/nulls/resources_container/output.txt vs /tmp/TestAcceptbundlevalidatenullsresources_containerDMS=3931516951/002/output.txt

latest (v1.23.0): same output as main (e9e2d63)

TestAccept/bundle/validate/nulls/resources_container/DMS=true: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌

main (e9e2d63):

acceptance_test.go:1341: 
        	Error Trace:	/home/runner/work/cli/cli/libs/testdiff/testdiff.go:22
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1341
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1082
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:659
        	Error:      	Not equal: 
        	            	expected: "\n>>> [CLI] bundle validate\nName: test-bundle\nTarget: default\nWorkspace:\n  User: [USERNAME]\n  Path: /Workspace/Users/[USERNAME]/.bundle/test-bundle/default\n\nValidation OK!\n"
        	            	actual  : "\n>>> [CLI] bundle validate\nError: expected a map at \"resources\", found nil\n\nName: test-bundle\n\nFound 1 error\n\nExit code: 1\n"
        	            	
        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -2,9 +2,9 @@
        	            	 >>> [CLI] bundle validate
        	            	+Error: expected a map at "resources", found nil
        	            	+
        	            	 Name: test-bundle
        	            	-Target: default
        	            	-Workspace:
        	            	-  User: [USERNAME]
        	            	-  Path: /Workspace/Users/[USERNAME]/.bundle/test-bundle/default
        	            	 
        	            	-Validation OK!
        	            	+Found 1 error
        	            	 
        	            	+Exit code: 1
        	            	+
        	Test:       	TestAccept/bundle/validate/nulls/resources_container/DMS=true
        	Messages:   	bundle/validate/nulls/resources_container/output.txt vs /tmp/TestAcceptbundlevalidatenullsresources_containerDMS=true4167336662/002/output.txt

latest (v1.23.0): same output as main (e9e2d63)

TestAccept/bundle/validate/nulls/root_without_base/DMS=: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌

main (e9e2d63):

acceptance_test.go:1341: 
        	Error Trace:	/home/runner/work/cli/cli/libs/testdiff/testdiff.go:22
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1341
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1082
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:659
        	Error:      	Not equal: 
        	            	expected: "\n>>> [CLI] bundle validate -o json\n{\n  \"email_notifications\": {},\n  \"max_concurrent_runs\": 1,\n  \"name\": \"foo\",\n  \"queue\": {\n    \"enabled\": true\n  },\n  \"tags\": {\n    \"kept\": \"1\"\n  }\n}\n"
        	            	actual  : "\n>>> [CLI] bundle validate -o json\nWarning: expected a string value, found null\n  at resources.jobs.foo.description\n  in databricks.yml:8:20\n\nWarning: expected a string value, found null\n  at resources.jobs.foo.tags.not_in_base\n  in databricks.yml:11:22\n\n{\n  \"email_notifications\": {\n    \"on_failure\": null\n  },\n  \"max_concurrent_runs\": 1,\n  \"name\": \"foo\",\n  \"queue\": {\n    \"enabled\": true\n  },\n  \"tags\": {\n    \"kept\": \"1\"\n  }\n}\n"
        	            	
        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -2,4 +2,14 @@
        	            	 >>> [CLI] bundle validate -o json
        	            	+Warning: expected a string value, found null
        	            	+  at resources.jobs.foo.description
        	            	+  in databricks.yml:8:20
        	            	+
        	            	+Warning: expected a string value, found null
        	            	+  at resources.jobs.foo.tags.not_in_base
        	            	+  in databricks.yml:11:22
        	            	+
        	            	 {
        	            	-  "email_notifications": {},
        	            	+  "email_notifications": {
        	            	+    "on_failure": null
        	            	+  },
        	            	   "max_concurrent_runs": 1,
        	Test:       	TestAccept/bundle/validate/nulls/root_without_base/DMS=
        	Messages:   	bundle/validate/nulls/root_without_base/output.txt vs /tmp/TestAcceptbundlevalidatenullsroot_without_baseDMS=3321558057/002/output.txt

latest (v1.23.0): same output as main (e9e2d63)

TestAccept/bundle/validate/nulls/root_without_base/DMS=true: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌

main (e9e2d63):

acceptance_test.go:1341: 
        	Error Trace:	/home/runner/work/cli/cli/libs/testdiff/testdiff.go:22
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1341
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1082
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:659
        	Error:      	Not equal: 
        	            	expected: "\n>>> [CLI] bundle validate -o json\n{\n  \"email_notifications\": {},\n  \"max_concurrent_runs\": 1,\n  \"name\": \"foo\",\n  \"queue\": {\n    \"enabled\": true\n  },\n  \"tags\": {\n    \"kept\": \"1\"\n  }\n}\n"
        	            	actual  : "\n>>> [CLI] bundle validate -o json\nWarning: expected a string value, found null\n  at resources.jobs.foo.description\n  in databricks.yml:8:20\n\nWarning: expected a string value, found null\n  at resources.jobs.foo.tags.not_in_base\n  in databricks.yml:11:22\n\n{\n  \"email_notifications\": {\n    \"on_failure\": null\n  },\n  \"max_concurrent_runs\": 1,\n  \"name\": \"foo\",\n  \"queue\": {\n    \"enabled\": true\n  },\n  \"tags\": {\n    \"kept\": \"1\"\n  }\n}\n"
        	            	
        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -2,4 +2,14 @@
        	            	 >>> [CLI] bundle validate -o json
        	            	+Warning: expected a string value, found null
        	            	+  at resources.jobs.foo.description
        	            	+  in databricks.yml:8:20
        	            	+
        	            	+Warning: expected a string value, found null
        	            	+  at resources.jobs.foo.tags.not_in_base
        	            	+  in databricks.yml:11:22
        	            	+
        	            	 {
        	            	-  "email_notifications": {},
        	            	+  "email_notifications": {
        	            	+    "on_failure": null
        	            	+  },
        	            	   "max_concurrent_runs": 1,
        	Test:       	TestAccept/bundle/validate/nulls/root_without_base/DMS=true
        	Messages:   	bundle/validate/nulls/root_without_base/output.txt vs /tmp/TestAcceptbundlevalidatenullsroot_without_baseDMS=true624828748/002/output.txt

latest (v1.23.0): same output as main (e9e2d63)

TestAccept/bundle/validate/nulls/schedule_default_materialization/DMS=: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌

main (e9e2d63):

acceptance_test.go:1341: 
        	Error Trace:	/home/runner/work/cli/cli/libs/testdiff/testdiff.go:22
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1341
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1082
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:659
        	Error:      	Not equal: 
        	            	expected: "\n>>> [CLI] bundle validate -o json\n{\n  \"schedule\": null\n}\n"
        	            	actual  : "\n>>> [CLI] bundle validate -o json\nWarning: required field \"quartz_cron_expression\" is not set\n  at resources.jobs.j.schedule\n  in databricks.yml:8:17\n\nWarning: required field \"timezone_id\" is not set\n  at resources.jobs.j.schedule\n  in databricks.yml:8:17\n\n{\n  \"schedule\": null\n}\n"
        	            	
        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -2,2 +2,10 @@
        	            	 >>> [CLI] bundle validate -o json
        	            	+Warning: required field "quartz_cron_expression" is not set
        	            	+  at resources.jobs.j.schedule
        	            	+  in databricks.yml:8:17
        	            	+
        	            	+Warning: required field "timezone_id" is not set
        	            	+  at resources.jobs.j.schedule
        	            	+  in databricks.yml:8:17
        	            	+
        	            	 {
        	Test:       	TestAccept/bundle/validate/nulls/schedule_default_materialization/DMS=
        	Messages:   	bundle/validate/nulls/schedule_default_materialization/output.txt vs /tmp/TestAcceptbundlevalidatenullsschedule_default_materializatio1991151169/002/output.txt

latest (v1.23.0): same output as main (e9e2d63)

TestAccept/bundle/validate/nulls/schedule_default_materialization/DMS=true: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌

main (e9e2d63):

acceptance_test.go:1341: 
        	Error Trace:	/home/runner/work/cli/cli/libs/testdiff/testdiff.go:22
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1341
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1082
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:659
        	Error:      	Not equal: 
        	            	expected: "\n>>> [CLI] bundle validate -o json\n{\n  \"schedule\": null\n}\n"
        	            	actual  : "\n>>> [CLI] bundle validate -o json\nWarning: required field \"quartz_cron_expression\" is not set\n  at resources.jobs.j.schedule\n  in databricks.yml:8:17\n\nWarning: required field \"timezone_id\" is not set\n  at resources.jobs.j.schedule\n  in databricks.yml:8:17\n\n{\n  \"schedule\": null\n}\n"
        	            	
        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -2,2 +2,10 @@
        	            	 >>> [CLI] bundle validate -o json
        	            	+Warning: required field "quartz_cron_expression" is not set
        	            	+  at resources.jobs.j.schedule
        	            	+  in databricks.yml:8:17
        	            	+
        	            	+Warning: required field "timezone_id" is not set
        	            	+  at resources.jobs.j.schedule
        	            	+  in databricks.yml:8:17
        	            	+
        	            	 {
        	Test:       	TestAccept/bundle/validate/nulls/schedule_default_materialization/DMS=true
        	Messages:   	bundle/validate/nulls/schedule_default_materialization/output.txt vs /tmp/TestAcceptbundlevalidatenullsschedule_default_materializatio2269327520/002/output.txt

latest (v1.23.0): same output as main (e9e2d63)

TestAccept/bundle/validate/nulls/target_keyed_slices/DMS=: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌

main (e9e2d63):

acceptance_test.go:1341: Diff:
        --- bundle/validate/nulls/target_keyed_slices/output.txt
        +++ /tmp/TestAcceptbundlevalidatenullstarget_keyed_slicesDMS=768488341/002/output.txt
        @@ -1,29 +1,46 @@
         
         >>> [CLI] bundle validate -o json -t dev
        -Warning: required field "default" is not set
        -  at resources.jobs.foo.parameters[0]
        -  in databricks.yml:15:11
        -     databricks.yml:47:15
        +Warning: expected a int value, found null
        +  at targets.dev.resources.jobs.foo.job_clusters[0].new_cluster.num_workers
        +  in databricks.yml:45:30
         
        +Warning: expected a string value, found null
        +  at targets.dev.resources.jobs.foo.parameters[0].default
        +  in databricks.yml:48:24
        +
        +Warning: expected a int value, found null
        +  at targets.dev.resources.jobs.foo.tasks[0].max_retries
        +  in databricks.yml:51:28
        +
        +Warning: expected a int value, found null
        +  at targets.dev.resources.jobs.foo.tasks[1].max_retries
        +  in databricks.yml:54:28
        +
        +Warning: expected a int value, found null
        +  at targets.dev.resources.pipelines.bar.clusters[0].num_workers
        +  in databricks.yml:61:28
        +
         {
           "job_clusters": [
             {
               "job_cluster_key": "c1",
               "new_cluster": {
                 "node_type_id": "[NODE_TYPE_ID]",
        -        "num_workers": 0,
        +        "num_workers": 2,
                 "spark_version": "15.4.x-scala2.12"
               }
             }
           ],
           "parameters": [
             {
        +      "default": "base",
               "name": "p1"
             }
           ],
           "tasks": [
             {
               "job_cluster_key": "c1",
        +      "max_retries": 3,
               "notebook_task": {
                 "notebook_path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/dev/files/nb"
               },
        @@ -49,7 +47,8 @@
           "pipeline_clusters": [
             {
               "label": "default",
        -      "node_type_id": "[NODE_TYPE_ID]"
        +      "node_type_id": "[NODE_TYPE_ID]",
        +      "num_workers": 2
             }
           ]
         }

latest (v1.23.0): same output as main (e9e2d63)

TestAccept/bundle/validate/nulls/target_keyed_slices/DMS=true: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌

main (e9e2d63):

acceptance_test.go:1341: Diff:
        --- bundle/validate/nulls/target_keyed_slices/output.txt
        +++ /tmp/TestAcceptbundlevalidatenullstarget_keyed_slicesDMS=true2297048655/002/output.txt
        @@ -1,29 +1,46 @@
         
         >>> [CLI] bundle validate -o json -t dev
        -Warning: required field "default" is not set
        -  at resources.jobs.foo.parameters[0]
        -  in databricks.yml:15:11
        -     databricks.yml:47:15
        +Warning: expected a int value, found null
        +  at targets.dev.resources.jobs.foo.job_clusters[0].new_cluster.num_workers
        +  in databricks.yml:45:30
         
        +Warning: expected a string value, found null
        +  at targets.dev.resources.jobs.foo.parameters[0].default
        +  in databricks.yml:48:24
        +
        +Warning: expected a int value, found null
        +  at targets.dev.resources.jobs.foo.tasks[0].max_retries
        +  in databricks.yml:51:28
        +
        +Warning: expected a int value, found null
        +  at targets.dev.resources.jobs.foo.tasks[1].max_retries
        +  in databricks.yml:54:28
        +
        +Warning: expected a int value, found null
        +  at targets.dev.resources.pipelines.bar.clusters[0].num_workers
        +  in databricks.yml:61:28
        +
         {
           "job_clusters": [
             {
               "job_cluster_key": "c1",
               "new_cluster": {
                 "node_type_id": "[NODE_TYPE_ID]",
        -        "num_workers": 0,
        +        "num_workers": 2,
                 "spark_version": "15.4.x-scala2.12"
               }
             }
           ],
           "parameters": [
             {
        +      "default": "base",
               "name": "p1"
             }
           ],
           "tasks": [
             {
               "job_cluster_key": "c1",
        +      "max_retries": 3,
               "notebook_task": {
                 "notebook_path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/dev/files/nb"
               },
        @@ -49,7 +47,8 @@
           "pipeline_clusters": [
             {
               "label": "default",
        -      "node_type_id": "[NODE_TYPE_ID]"
        +      "node_type_id": "[NODE_TYPE_ID]",
        +      "num_workers": 2
             }
           ]
         }

latest (v1.23.0): same output as main (e9e2d63)

TestAccept/bundle/validate/nulls/target_removes_job_fields/DMS=: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌

main (e9e2d63):

acceptance_test.go:1341: Diff:
        --- bundle/validate/nulls/target_removes_job_fields/output.txt
        +++ /tmp/TestAcceptbundlevalidatenullstarget_removes_job_fieldsDMS=1474214315/002/output.txt
        @@ -1,22 +1,51 @@
         
         >>> [CLI] bundle validate -o json -t dev
        +Warning: expected a string value, found null
        +  at targets.dev.resources.jobs.foo.description
        +  in databricks.yml:30:24
        +
        +Warning: expected a int value, found null
        +  at targets.dev.resources.jobs.foo.max_concurrent_runs
        +  in databricks.yml:31:32
        +
        +Warning: expected a string value, found null
        +  at targets.dev.resources.jobs.foo.schedule.pause_status
        +  in databricks.yml:34:27
        +
        +Warning: expected a string value, found null
        +  at targets.dev.resources.jobs.foo.tags.removed
        +  in databricks.yml:36:22
        +
        +Warning: expected a string value, found null
        +  at targets.dev.resources.jobs.foo.tags.not_in_base
        +  in databricks.yml:37:26
        +
        +Warning: expected a int value, found null
        +  at targets.dev.resources.jobs.foo.timeout_seconds
        +  in databricks.yml:40:28
        +
         {
        +  "description": "base description",
           "email_notifications": {
        +    "on_failure": [
        +      "base@example.com"
        +    ],
             "on_success": [
               "base@example.com"
             ]
           },
        -  "max_concurrent_runs": 1,
        +  "max_concurrent_runs": 5,
           "name": "foo",
           "queue": {
        -    "enabled": true
        +    "enabled": false
           },
           "schedule": {
        -    "pause_status": "UNPAUSED",
        +    "pause_status": "PAUSED",
             "quartz_cron_expression": "0 0 * * * ?",
             "timezone_id": "UTC"
           },
           "tags": {
        -    "kept": "1"
        +    "kept": "1",
        +    "removed": "1"
           }
         }

latest (v1.23.0): same output as main (e9e2d63)

9 more failure details omitted, see the full report in the run.

@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: b7e451e

Run: 41074741153

Env ✅​pass 🙈​skip Time
✅​ aws linux-2core-8gb 284 28 5:35
✅​ aws-windows-latest-4core-16gb 286 26 5:57
✅​ azure linux-2core-8gb 283 28 5:32
✅​ azure-windows-latest-4core-16gb 285 26 4:10
✅​ gcp linux-2core-8gb 284 28 5:27
✅​ gcp-windows-latest-4core-16gb 286 26 4:06
Top 6 slowest tests (at least 2 minutes):
duration env testname
5:10 aws-windows-latest-4core-16gb TestAccept
3:54 azure linux-2core-8gb TestAccept
3:48 aws linux-2core-8gb TestAccept
3:33 gcp linux-2core-8gb TestAccept
3:29 azure-windows-latest-4core-16gb TestAccept
3:27 gcp-windows-latest-4core-16gb TestAccept

An empty resources.<type>.<name>, artifacts.<name> or scripts.<name> in a
file is kept as a declaration, like an empty target or variable, so that
it is still reported as undefined or not configured.

Target nulls are applied with MergeRemovingNulls instead of dropping all
nulls at the end, which removed those declarations too. Keyed sequences
with nulls are merged by key with the root before the fields are merged.

Co-authored-by: Isaac <no-reply@databricks.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

DABs DABs related issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants