{"record":{"id":"9f034d206fbfb944","repo":"hashicorp/terraform","slug":"formatvaluestr-error-dynamic","errorCode":null,"errorMessage":"FormatValueStr error (dynamic)","messagePattern":"FormatValueStr error \\(dynamic\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"internal/command/views/json/diagnostic.go","lineNumber":278,"sourceCode":"\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttraversalStr := tfdiags.TraversalStr(traversal)\n\t\t\t\t\t\tif _, exists := seen[traversalStr]; exists {\n\t\t\t\t\t\t\tcontinue Traversals // don't show duplicates when the same variable is referenced multiple times\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvalue := DiagnosticExpressionValue{\n\t\t\t\t\t\t\tTraversal: traversalStr,\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// If the diagnostic is caused by a failed run assertion,\n\t\t\t\t\t\t// we'll redact sensitive and ephemeral values within traversals, but format\n\t\t\t\t\t\t// the values in a more human-readable way than the general case.\n\t\t\t\t\t\t// If the value is unknown, we'll leave it to the general case to handle.\n\t\t\t\t\t\tif testDiag != nil && val.IsKnown() {\n\t\t\t\t\t\t\tvalBuf, err := tfdiags.FormatValueStr(val)\n\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\tpanic(err)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tvalue.Statement = fmt.Sprintf(\"is %s\", valBuf)\n\t\t\t\t\t\t\tvalues = append(values, value)\n\t\t\t\t\t\t\tseen[traversalStr] = struct{}{}\n\t\t\t\t\t\t\tcontinue Traversals\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstmt, ok := statementStr(val, includeUnknown, includeSensitive, includeEphemeral)\n\t\t\t\t\t\tif !ok {\n\t\t\t\t\t\t\tcontinue Traversals\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvalue.Statement = stmt\n\t\t\t\t\t\tvalues = append(values, value)\n\t\t\t\t\t\tseen[traversalStr] = struct{}{}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tsort.Slice(values, func(i, j int) bool {","sourceCodeStart":260,"sourceCodeEnd":296,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/command/views/json/diagnostic.go#L260-L296","documentation":"This panic fires in the diagnostic-expression-value formatter when tfdiags.FormatValueStr(val) returns a non-nil error for a single value inside a failed test-run assertion. FormatValueStr errors when cty.Transform or ctyjson.Marshal fails — i.e. the cty.Value is malformed, has an unsupported type for JSON, or carries marks that break marshalling.","triggerScenarios":"Evaluating a `terraform test` run-block assertion that failed, while rendering its expression-value diagnostics as JSON. The value must be known (!val.IsKnown() is excluded above). Fires when that known value's cty.Transform or ctyjson.Marshal step returns an error — e.g. a nested value of a type ctyjson cannot serialize, or a value carrying a custom mark unknown to the marshaller.","commonSituations":"A test fixture references a value of an unusual cty type (e.g. a capsule type, a dynamic pseudo-type, or a deep nested object) inside an assertion, and the diagnostic renderer crashes instead of degrading gracefully. Rare; most primitive/collection/object types marshal cleanly.","solutions":["Simplify the assertion expression in the test fixture (prefer primitive or simple collection values) and re-run `terraform test`.","If you maintain tfdiags.FormatValueStr, return an error-string fallback rather than panic-ing in the renderer.","Report the value's cty type/marks from the panic stack trace to narrow down which cty path is unserializable."],"exampleFix":"// before — renderer panics on marshal error\nvalBuf, err := tfdiags.FormatValueStr(val)\nif err != nil { panic(err) }\n// after — degrade gracefully (maintainer fix)\nvalBuf, err := tfdiags.FormatValueStr(val)\nif err != nil {\n  value.Statement = fmt.Sprintf(\"is <unable to render value: %s>\", err)\n} else {\n  value.Statement = fmt.Sprintf(\"is %s\", valBuf)\n}","handlingStrategy":"try-catch","validationCode":"// Probe-render the value before relying on it.\nif _, err := tfdiags.FormatValueStr(val); err != nil {\n  log.Printf(\"warn: unrenderable value: %v\", err)\n}","typeGuard":"// n/a — cty.Value; cannot statically narrow serializability","tryCatchPattern":"valBuf, err := tfdiags.FormatValueStr(val)\nif err != nil {\n  value.Statement = fmt.Sprintf(\"is <unrenderable: %s>\", err)\n} else {\n  value.Statement = fmt.Sprintf(\"is %s\", valBuf)\n}","preventionTips":["Avoid exotic cty types (capsule, dynamic pseudo-type) in test assertion values.","In renderer code, never panic on a formatting error — degrade to a placeholder.","Add fuzz tests over cty values passed to FormatValueStr to surface unserializable shapes."],"tags":["terraform-cli","diagnostics","cty","json","panic","invariant","test"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}