Terraform jsonencode() / yamlencode() Errors in CI
jsonencode()/yamlencode() serialize a Terraform value to JSON/YAML. They error when the value contains something they cannot represent, or when a referenced field is null/unknown at the point of encoding.
What this error means
plan fails inside a jsonencode()/yamlencode() call - often building an IAM policy document or a Kubernetes manifest - because a nested value is null, unknown, or an unsupported type.
Error: Error in function call
on iam.tf line 4, in resource "aws_iam_role_policy" "app":
4: policy = jsonencode({ Statement = local.statements })
Call to function "jsonencode" failed: unsupported value: a null value cannot be
serialized as part of this JSON document.Common causes
Null or unknown nested value
A field in the structure being encoded resolves to null (an unset optional) or is unknown until apply, which the encoder cannot serialize cleanly.
Unsupported value type
Passing a type the function cannot represent (for example a resource reference object instead of its concrete attributes) makes encoding fail.
How to fix it
Strip nulls and supply concrete values
Build the structure from concrete, non-null values; drop optional keys when their value is null.
locals {
statement = merge(
{ Effect = "Allow", Action = var.actions, Resource = var.resource },
var.condition == null ? {} : { Condition = var.condition }
)
}
resource "aws_iam_role_policy" "app" {
policy = jsonencode({ Version = "2012-10-17", Statement = [local.statement] })
}Encode concrete attributes, not objects
- Reference concrete attribute values (strings/numbers/lists), not whole resource objects.
- Default optional variables so they are not null at encode time.
- For apply-time-unknown values, ensure they are at least typed/known by the time the encode runs.
How to prevent it
- Default optional variables to avoid null fields in encoded structures.
- Omit map keys conditionally rather than setting them to null.
- Encode concrete attributes, not resource reference objects.