Skip to content

Commit acd6a7e

Browse files
authored
Merge pull request #38264 from hashicorp/jbardin/path-matcher
diff: don't panic on invalid keys for relevant attrs
2 parents 28f4d4b + 8f9bd87 commit acd6a7e

File tree

3 files changed

+56
-8
lines changed

3 files changed

+56
-8
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
kind: BUG FIXES
2+
body: Prevent crash in the display of relevant attributes after provider upgrades
3+
time: 2026-03-11T16:38:04.50368-04:00
4+
custom:
5+
Issue: "38264"

internal/command/jsonformat/structured/attribute_path/matcher.go

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818
//
1919
// The caller of the above functions is required to know whether the next value
2020
// in the path is a list type or an object type and call the relevant function,
21-
// otherwise these functions will crash/panic.
21+
// otherwise no match will be returned.
2222
//
2323
// The Matches function returns true if the paths you have traversed until now
2424
// ends.
@@ -151,8 +151,18 @@ func (p *PathMatcher) GetChildWithKey(key string) Matcher {
151151
continue
152152
}
153153

154-
if path[0].(string) == key {
155-
child.Paths = append(child.Paths, path[1:])
154+
switch val := path[0].(type) {
155+
case string:
156+
if val == key {
157+
child.Paths = append(child.Paths, path[1:])
158+
}
159+
case float64:
160+
// here we must assume the path being looked up no longer matches
161+
// the given data structure, so the caller in incorrect. This is
162+
// fine, because it only means that we don't match any paths.
163+
default:
164+
panic(fmt.Errorf("found invalid type within path (%v:%T), the validation shouldn't have allowed this to happen; this is a bug in Terraform, please report it", val, val))
165+
156166
}
157167
}
158168
return child
@@ -190,15 +200,12 @@ func (p *PathMatcher) GetChildWithIndex(index int) Matcher {
190200

191201
switch val := path[0].(type) {
192202
case float64:
193-
if int(path[0].(float64)) == index {
203+
if int(val) == index {
194204
child.Paths = append(child.Paths, path[1:])
195205
}
196206
case string:
197207
f, err := strconv.ParseFloat(val, 64)
198-
if err != nil {
199-
panic(fmt.Errorf("found invalid type within path (%v:%T), the validation shouldn't have allowed this to happen; this is a bug in Terraform, please report it", val, val))
200-
}
201-
if int(f) == index {
208+
if err == nil && int(f) == index {
202209
child.Paths = append(child.Paths, path[1:])
203210
}
204211
default:

internal/command/jsonformat/structured/attribute_path/matcher_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,3 +254,39 @@ func TestPathMatcher_MultiplePaths(t *testing.T) {
254254
t.Errorf("should not have partial matched at leaf level")
255255
}
256256
}
257+
258+
// Since paths may be coming from relevant attributes, and those paths may no
259+
// longer correspond to an updated schema, we can't always be certain the caller
260+
// knows the correct type.
261+
func TestPathMatcher_WrongKeyTypes(t *testing.T) {
262+
var matcher Matcher
263+
264+
matcher = &PathMatcher{
265+
Paths: [][]interface{}{
266+
{
267+
float64(0),
268+
"key",
269+
float64(0),
270+
},
271+
},
272+
}
273+
274+
failed := matcher.GetChildWithKey("key")
275+
if failed.Matches() || failed.MatchesPartial() {
276+
t.Errorf("should not have any match at on failure")
277+
}
278+
279+
matcher = matcher.GetChildWithIndex(0).GetChildWithKey("key")
280+
281+
if matcher.Matches() {
282+
t.Errorf("should not have exact matched at first level")
283+
}
284+
if !matcher.MatchesPartial() {
285+
t.Errorf("should have partial matched at first level")
286+
}
287+
288+
failed = matcher.GetChildWithKey("zero")
289+
if failed.Matches() || failed.MatchesPartial() {
290+
t.Errorf("should not have any match at on failure")
291+
}
292+
}

0 commit comments

Comments
 (0)