states: fix RootOutputValuesEqual comparing s2 to itself#38181
states: fix RootOutputValuesEqual comparing s2 to itself#38181SarahFrench merged 3 commits intohashicorp:mainfrom
Conversation
RootOutputValuesEqual had a copy-paste bug where it iterated over s2.RootOutputValues instead of s.RootOutputValues, effectively comparing s2 against itself rather than comparing the receiver (s) against the argument (s2). This meant the function would always return true as long as both states had the same number of output values, regardless of whether the actual values differed. This bug was introduced in hashicorp#37886 and affects refresh-only plan mode, where RootOutputValuesEqual is used to determine if root output values changed during refresh, which controls whether the plan is considered applyable.
|
Hi @veeceey, is there an issue open for this bug? Thanks. |
|
Hey @crw, I don't think there's an existing issue for this — I found it while reading through the changes in #37886. The bug is pretty straightforward: the loop iterates over Happy to open an issue first if that's preferred! |
SarahFrench
left a comment
There was a problem hiding this comment.
H! @veeceey , thanks for spotting this!
I don't think you need to open an issue, but it'd be good to establish whether this is a bug that could change user-facing behaviour. If the bug wasn't user facing then we wouldn't include a change log entry.
From the original PR it looks like it could be user facing but only in some specific conditions:
These comparison are not used in any critical codepaths, but do show up in unexpected places, like backend migrations which don't appear to be needed, or incorrect exit codes when there are no changes planned.
I've proposed a change to the change log entry that frames things from a user's perspective. If you're happy to go ahead with that I'm happy to get this merged.
| @@ -0,0 +1,5 @@ | |||
| kind: BUG FIXES | |||
| body: 'states: fix `RootOutputValuesEqual` comparing `s2` to itself instead of comparing `s` to `s2`, which caused refresh-only plans to never detect output value changes' | |||
There was a problem hiding this comment.
| body: 'states: fix `RootOutputValuesEqual` comparing `s2` to itself instead of comparing `s` to `s2`, which caused refresh-only plans to never detect output value changes' | |
| body: 'states: fixed a bug that caused Terraform to be unable to identify when two states had different output values. This may have caused issues in specific circumstances like backend migrations. |
There was a problem hiding this comment.
Thanks @SarahFrench — that wording is much better! I've pushed the update. Happy to merge whenever you're ready.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
I'm going to lock this pull request because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active contributions. |
Description
RootOutputValuesEqualhas a bug where it iterates overs2.RootOutputValuesinstead ofs.RootOutputValues, so it ends up comparings2against itself rather than comparings(the receiver) againsts2(the argument).This means the function always returns
truewhen both states have the same number of output values, even if the values themselves are completely different. This was introduced in #37886.Impact
This affects refresh-only plan mode (
terraform plan -refresh-only), whereRootOutputValuesEqualis used to determine whether root output values changed during refresh. With this bug, output value changes during refresh would never cause the plan to be considered applyable, since the comparison always reports equality.Test plan
TestStateRootOutputValuesEqualcovering identical outputs, differing values, differing sensitivity, differing keys with same count, and differing countstruebefore this fixinternal/statestests continue to pass