From b2fc2caf726f250c52fb64326db153c6b8b29907 Mon Sep 17 00:00:00 2001 From: Sarah French <15078782+SarahFrench@users.noreply.github.com> Date: Thu, 4 Jun 2026 15:56:00 +0100 Subject: [PATCH] fix: Remove deprecation marks when formatting output for the `console` command. (#38676) This change introduces handling of deprecation marks to resolve the linked issue, where the `console` command would panic when displaying a deprecated field, either directly, as part of a whole resource, or when referenced within a resource/local/etc. Deprecation marks aren't used to change how values are rendered, but they need to be removed before we use the cty library to get string representations of values. I decided to only remove marks in the context of a deprecation mark being present; if a different type of mark is added in future then the engineer implementing it will need to make an explicit decision about how it should be handled in the context of `console`. If that isn't done then the panic from the cty library will re-appear. --- .changes/v1.15/BUG FIXES-20260603-172507.yaml | 5 +++++ internal/repl/format.go | 9 +++++++++ internal/repl/format_test.go | 4 ++++ 3 files changed, 18 insertions(+) create mode 100644 .changes/v1.15/BUG FIXES-20260603-172507.yaml diff --git a/.changes/v1.15/BUG FIXES-20260603-172507.yaml b/.changes/v1.15/BUG FIXES-20260603-172507.yaml new file mode 100644 index 0000000000..c8487e4044 --- /dev/null +++ b/.changes/v1.15/BUG FIXES-20260603-172507.yaml @@ -0,0 +1,5 @@ +kind: BUG FIXES +body: 'console: Fixed a panic caused by evaluating an expression involving deprecated values' +time: 2026-06-03T17:25:07.111161+01:00 +custom: + Issue: "38676" diff --git a/internal/repl/format.go b/internal/repl/format.go index fd0bc4b20e..3f33352e1c 100644 --- a/internal/repl/format.go +++ b/internal/repl/format.go @@ -20,12 +20,21 @@ func FormatValue(v cty.Value, indent int) string { if !v.IsKnown() { return "(known after apply)" } + + // Any marks on the value must either be used to return + // early or be removed. In future marks may used to cause + // values to be annotated, but the mark will still need to be + // removed before we can get a string representation of the value. if marks.Has(v, marks.Sensitive) { return "(sensitive value)" } if marks.Has(v, marks.Ephemeral) { return "(ephemeral value)" } + if marks.Has(v, marks.Deprecation) { + // Mark doesn't impact formatting, so remove to unblock normal formatting below + v, _ = v.Unmark() + } if v.IsNull() { ty := v.Type() switch { diff --git a/internal/repl/format_test.go b/internal/repl/format_test.go index 9e6e4c9b9f..89d40d1a23 100644 --- a/internal/repl/format_test.go +++ b/internal/repl/format_test.go @@ -181,6 +181,10 @@ EOT_`, cty.StringVal("an ephemeral value").Mark(marks.Ephemeral), "(ephemeral value)", }, + { + cty.StringVal("I'm a deprecated string value").Mark(marks.Deprecation), + `"I'm a deprecated string value"`, // We don't render deprecated values differently, but we need to ensure the deprecation mark doesn't interfere with formatting + }, } for _, test := range tests {