Skip to content

[monitor] Fix panic when dynamic variables block is empty#3846

Open
phillip-dd wants to merge 2 commits into
masterfrom
dd/handle-empty-dynamic-variables-block
Open

[monitor] Fix panic when dynamic variables block is empty#3846
phillip-dd wants to merge 2 commits into
masterfrom
dd/handle-empty-dynamic-variables-block

Conversation

@phillip-dd
Copy link
Copy Markdown
Contributor

Summary

Fixes a panic that occurs when a dynamic "variables" block in a Terraform configuration produces an empty variables {} block with no inner content. Fixes #3149

Problem

When using the wrapper-module pattern with a dynamic "variables" block that resolves to an empty block (no cloud_cost_query, event_query, or data_quality_query entries), the provider would crash during terraform plan with:

interface conversion: interface {} is nil, not map[string]interface {}

This occurred in the buildMonitorStruct function when attempting to type-assert nil values from the Terraform configuration.

Solution

Added defensive checks in buildMonitorStruct to:

  1. Skip nil elements in the variables list
  2. Safely perform type assertions on variable maps and query lists using the comma-ok pattern
  3. Continue processing instead of panicking when encountering nil or unexpected types

These changes allow empty variables {} blocks to be gracefully handled, resulting in no variables field being sent to the API (same behavior as omitting the block entirely).

Testing

Added TestAccDatadogMonitor_DynamicEmptyVariables test that verifies the provider can successfully create a monitor with an empty dynamic variables block, matching the real-world wrapper-module pattern from issue #3149.


PR by Bits - View session in Datadog

Comment @DataDog to request changes

Fix panic 'interface conversion: interface {} is nil, not
map[string]interface {}' in buildMonitorStruct when a variables block is
empty.

This shows up when an HCL dynamic block resolves to an empty
'variables {}' block — for example:

    dynamic "variables" {
      for_each = var.monitoring_variables != null ? [var.monitoring_variables] : []
      content {
        dynamic "cloud_cost_query" {
          for_each = var.monitoring_variables.cloud_cost_queries != null ? var.monitoring_variables.cloud_cost_queries : []
          content { ... }
        }
      }
    }

with 'monitoring_variables = { cloud_cost_queries = [] }'. The outer
variables block exists but has no inner content, and SDKv2 surfaces it
during PlanResourceChange/CustomizeDiff as a list containing a single
nil element. The unsafe type assertion 'v.(map[string]interface{})'
then panics and terraform plan crashes.

Add the same defensive nil-guards we already use for data_quality_query
/ aggregate_*_query / data_jobs_query at three places:

  - the outer 'variables' list iteration
  - the inner 'event_query' list iteration
  - the inner 'cloud_cost_query' list iteration

Nil entries are skipped, matching the existing pattern; if every entry
is nil, no variables are set on the monitor, which is the same result
as omitting the block.

Add unit tests that drive buildMonitorStruct with a stub Resource and
reproduce the original panic without the fix:

  - TestBuildMonitorStruct_NilVariableEntry
  - TestBuildMonitorStruct_NilCloudCostQueryEntry
  - TestBuildMonitorStruct_NilEventQueryEntry
Replace the previous unit tests with TestAccDatadogMonitor_DynamicEmptyVariables,
an acceptance test that exercises the wrapper-module pattern from issue #3149:
an outer 'dynamic "variables"' that always produces one block, and an inner
'dynamic "cloud_cost_query"' whose for_each resolves to an empty list. The
result is a single empty 'variables {}' block — exactly the input shape that
crashed buildMonitorStruct on master with

  panic: interface conversion: interface {} is nil, not map[string]interface {}

before the nil-guard fix in 2b011918.

Verified by temporarily reverting the production fix: the test reproduces the
exact panic from the issue, then passes once the fix is reapplied. The recorded
cassette mirrors TestAccDatadogMonitor_EmptySchedulingOptions (same monitor
shape, no priority, no variables field in any request body since the empty
block is filtered out).
@datadog-datadog-prod-us1
Copy link
Copy Markdown
Contributor

View session in Datadog

Bits Dev status: ✅ Done

CI Auto-fix: Disabled | Enable

Comment @DataDog to request changes

@phillip-dd phillip-dd requested a review from a team as a code owner June 2, 2026 00:24
@datadog-datadog-prod-us1-2
Copy link
Copy Markdown

I can only run on private repositories.

@datadog-datadog-prod-us1
Copy link
Copy Markdown
Contributor

datadog-datadog-prod-us1 Bot commented Jun 2, 2026

Pipelines

Fix all issues with BitsAI

⚠️ Warnings

🚦 1 Pipeline job failed

Ensure labels | changelog   View in Datadog   GitHub Actions

🛟 This job is unlikely to succeed on retry. Please review your pipeline configuration. Missing required label 'changelog/*'.

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 66747e5 | Docs | Datadog PR Page | Give us feedback!

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The terraform-provider-datadog_v3.66.0 plugin crashed

1 participant