@@ -4399,6 +4399,65 @@ resource "test_object" "b" {
43994399 }
44004400}
44014401
4402+ func TestContext2Plan_triggeredByInvalidAttribute (t * testing.T ) {
4403+ // This test verifies that referencing a non-existent attribute in
4404+ // replace_triggered_by produces an error.
4405+ m := testModuleInline (t , map [string ]string {
4406+ "main.tf" : `
4407+ resource "test_object" "a" {
4408+ test_string = "new"
4409+ }
4410+ resource "test_object" "b" {
4411+ test_string = "value"
4412+ lifecycle {
4413+ replace_triggered_by = [ test_object.a.nonexistent_attribute ]
4414+ }
4415+ }
4416+ ` ,
4417+ })
4418+
4419+ p := simpleMockProvider ()
4420+
4421+ ctx := testContext2 (t , & ContextOpts {
4422+ Providers : map [addrs.Provider ]providers.Factory {
4423+ addrs .NewDefaultProvider ("test" ): testProviderFuncFixed (p ),
4424+ },
4425+ })
4426+
4427+ state := states .BuildState (func (s * states.SyncState ) {
4428+ s .SetResourceInstanceCurrent (
4429+ mustResourceInstanceAddr ("test_object.a" ),
4430+ & states.ResourceInstanceObjectSrc {
4431+ AttrsJSON : []byte (`{"test_string":"old"}` ),
4432+ Status : states .ObjectReady ,
4433+ },
4434+ mustProviderConfig (`provider["registry.terraform.io/hashicorp/test"]` ),
4435+ )
4436+ s .SetResourceInstanceCurrent (
4437+ mustResourceInstanceAddr ("test_object.b" ),
4438+ & states.ResourceInstanceObjectSrc {
4439+ AttrsJSON : []byte (`{"test_string":"value"}` ),
4440+ Status : states .ObjectReady ,
4441+ },
4442+ mustProviderConfig (`provider["registry.terraform.io/hashicorp/test"]` ),
4443+ )
4444+ })
4445+
4446+ _ , diags := ctx .Plan (m , state , & PlanOpts {
4447+ Mode : plans .NormalMode ,
4448+ })
4449+ if ! diags .HasErrors () {
4450+ t .Fatal ("expected errors for invalid attribute reference in replace_triggered_by" )
4451+ }
4452+
4453+ // Check that the error message is about the invalid attribute reference.
4454+ // StaticValidateTraversal returns "Unsupported attribute" errors.
4455+ errMsg := diags .Err ().Error ()
4456+ if ! strings .Contains (errMsg , "Unsupported attribute" ) && ! strings .Contains (errMsg , "nonexistent_attribute" ) {
4457+ t .Fatalf ("unexpected error message: %s" , errMsg )
4458+ }
4459+ }
4460+
44024461func TestContext2Plan_dataSchemaChange (t * testing.T ) {
44034462 // We can't decode the prior state when a data source upgrades the schema
44044463 // in an incompatible way. Since prior state for data sources is purely
0 commit comments