Repository: hashicorp/terraform (Go)

Issue:
Terraform crashes in recent versions - invalid memory address or nil pointer dereference goroutine 3192
### Terraform Version

```shell
1.3.7
1.3.6
```


### Terraform Configuration Files

```terraform
...terraform config...
```


### Debug Output

!!!!!!!!!!!!!!!!!!!!!!!!!!! TERRAFORM CRASH !!!!!!!!!!!!!!!!!!!!!!!!!!!!

Terraform crashed! This is always indicative of a bug within Terraform.
Please report the crash with Terraform[1] so that we can fix this.

When reporting bugs, please include your terraform version, the stack trace
shown below, and any additional information which may help replicate the issue.

[1]: https://github.com/hashicorp/terraform/issues

!!!!!!!!!!!!!!!!!!!!!!!!!!! TERRAFORM CRASH !!!!!!!!!!!!!!!!!!!!!!!!!!!!

runtime error: invalid memory address or nil pointer dereference
goroutine 3192 [running]:
runtime/debug.Stack()
	/usr/local/go/src/runtime/debug/stack.go:24 +0x65
runtime/debug.PrintStack()
	/usr/local/go/src/runtime/debug/stack.go:16 +0x19
github.com/hashicorp/terraform/internal/logging.PanicHandler()
	/home/circleci/project/project/internal/logging/panic.go:55 +0x153
panic({0x223cde0, 0x3e36ac0})
	/usr/local/go/src/runtime/panic.go:884 +0x212
github.com/hashicorp/terraform/internal/terraform.(*NodePlannableResourceInstanceOrphan).managedResourceExecute(0xc003751440, {0x2b85518, 0xc00283a2a0})
	/home/circleci/project/project/internal/terraform/node_resource_plan_orphan.go:128 +0x415
github.com/hashicorp/terraform/internal/terraform.(*NodePlannableResourceInstanceOrphan).Execute(0x0?, {0x2b85518?, 0xc00283a2a0?}, 0x20?)
	/home/circleci/project/project/internal/terraform/node_resource_plan_orphan.go:49 +0x90
github.com/hashicorp/terraform/internal/terraform.(*ContextGraphWalker).Execute(0xc002e73c20, {0x2b85518, 0xc00283a2a0}, {0x7f239d5dfc98, 0xc003751440})
	/home/circleci/project/project/internal/terraform/graph_walk_context.go:136 +0xc2
github.com/hashicorp/terraform/internal/terraform.(*Graph).walk.func1({0x256df60, 0xc003751440})
	/home/circleci/project/project/internal/terraform/graph.go:74 +0x2f0
github.com/hashicorp/terraform/internal/dag.(*Walker).walkVertex(0xc002b09e60, {0x256df60, 0xc003751440}, 0xc006379a80)
	/home/circleci/project/project/internal/dag/walk.go:381 +0x2f6
created by github.com/hashicorp/terraform/internal/dag.(*Walker).Update
	/home/circleci/project/project/internal/dag/walk.go:304 +0xf65
time=2023-01-18T17:11:55Z level=error msg=1 error occurred:
	* exit status 11


***************************************
APPLY_RESULT = 11
***************************************

### Expected Behavior

Terraform should pass successfully, when downgrading the same code to v1.3.5 the code works

### Actual Behavior

Terraform crashes as shown with debug output above

### Steps to Reproduce

terraform init
terraform apply

### Additional Context

Using terragrunt to wrap the terraform command

### References

https://github.com/hashicorp/terraform/issues/30950


Discussion:
Hi @afzalch, thanks for reporting this issue.

Can you share a small configuration which reproduces this crash? Without being able to reproduce the problem it will be difficult to be sure that we've fixed it.
@alisdair, I don't yet have a repro for a test, but I can see where the problem came from. The `readResourceInstanceState` method was refactored in such a way that it returns a `nil` value with no errors for some cases. This is apparently used by other callers, so I think the best course of action is to add another guard here until we can verify all call sites.

> Hi @afzalch, thanks for reporting this issue.
> 
> Can you share a small configuration which reproduces this crash? Without being able to reproduce the problem it will be difficult to be sure that we've fixed it.

Hi @alisdair I've seen this error occurring in terraform 1.3.6 and up when using the hashicorp **Helm** and **Kubernetes** providers.
```
terraform {
  required_providers {
    helm = {
      source  = "hashicorp/helm"
      version = "~> 2.7.1"
    }
    kubernetes = {
      source  = "hashicorp/kubernetes"
      version = "~> 2.14.0"
    }
  }
}
```
Once you downgrade terrafrom version to 1.3.5, there is no crashing.
@joavilacr Thanks for sharing that. Are you able to reproduce this issue with a small Helm & Kubernetes configuration? I'm still not able to find any way to reproduce the issue.

Can you also share more about which commands you're using, with which CLI flags, and what state you are in when it occurs?
I've just merged two PRs which should fix this panic. They'll go out in the next 1.3 patch release, as well as in the upcoming 1.4.0. If you're able to build Terraform from the `v1.3` branch to check this, that'd be helpful. 
I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.



Patch:
diff --git a/internal/terraform/node_resource_plan_orphan.go b/internal/terraform/node_resource_plan_orphan.go
index aab78696fa29..c48e55b74fb2 100644
--- a/internal/terraform/node_resource_plan_orphan.go
+++ b/internal/terraform/node_resource_plan_orphan.go
@@ -125,7 +125,7 @@ func (n *NodePlannableResourceInstanceOrphan) managedResourceExecute(ctx EvalCon
 	// refresh indicates the instance no longer exists, there is also nothing
 	// to plan because there is no longer any state and it doesn't exist in the
 	// config.
-	if n.skipPlanChanges || oldState.Value.IsNull() {
+	if n.skipPlanChanges || oldState == nil || oldState.Value.IsNull() {
 		return diags.Append(n.writeResourceInstanceState(ctx, oldState, workingState))
 	}
 


Test patch:
diff --git a/internal/terraform/node_resource_plan_orphan_test.go b/internal/terraform/node_resource_plan_orphan_test.go
index deed93bb9b6c..0a29decc5639 100644
--- a/internal/terraform/node_resource_plan_orphan_test.go
+++ b/internal/terraform/node_resource_plan_orphan_test.go
@@ -141,3 +141,70 @@ func TestNodeResourcePlanOrphanExecute_alreadyDeleted(t *testing.T) {
 		t.Errorf("there should be no change for the %s instance, got %s", addr, got.Action)
 	}
 }
+
+// This test describes a situation which should not be possible, as this node
+// should never work on deposed instances. However, a bug elsewhere resulted in
+// this code path being exercised and triggered a panic. As a result, the
+// assertions at the end of the test are minimal, as the behaviour (aside from
+// not panicking) is unspecified.
+func TestNodeResourcePlanOrphanExecute_deposed(t *testing.T) {
+	addr := addrs.Resource{
+		Mode: addrs.ManagedResourceMode,
+		Type: "test_object",
+		Name: "foo",
+	}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance)
+
+	state := states.NewState()
+	state.Module(addrs.RootModuleInstance).SetResourceInstanceDeposed(
+		addr.Resource,
+		states.NewDeposedKey(),
+		&states.ResourceInstanceObjectSrc{
+			AttrsFlat: map[string]string{
+				"test_string": "foo",
+			},
+			Status: states.ObjectReady,
+		},
+		addrs.AbsProviderConfig{
+			Provider: addrs.NewDefaultProvider("test"),
+			Module:   addrs.RootModule,
+		},
+	)
+	refreshState := state.DeepCopy()
+	prevRunState := state.DeepCopy()
+	changes := plans.NewChanges()
+
+	p := simpleMockProvider()
+	p.ConfigureProvider(providers.ConfigureProviderRequest{})
+	p.ReadResourceResponse = &providers.ReadResourceResponse{
+		NewState: cty.NullVal(p.GetProviderSchemaResponse.ResourceTypes["test_string"].Block.ImpliedType()),
+	}
+	ctx := &MockEvalContext{
+		StateState:               state.SyncWrapper(),
+		RefreshStateState:        refreshState.SyncWrapper(),
+		PrevRunStateState:        prevRunState.SyncWrapper(),
+		InstanceExpanderExpander: instances.NewExpander(),
+		ProviderProvider:         p,
+		ProviderSchemaSchema: &ProviderSchema{
+			ResourceTypes: map[string]*configschema.Block{
+				"test_object": simpleTestSchema(),
+			},
+		},
+		ChangesChanges: changes.SyncWrapper(),
+	}
+
+	node := NodePlannableResourceInstanceOrphan{
+		NodeAbstractResourceInstance: &NodeAbstractResourceInstance{
+			NodeAbstractResource: NodeAbstractResource{
+				ResolvedProvider: addrs.AbsProviderConfig{
+					Provider: addrs.NewDefaultProvider("test"),
+					Module:   addrs.RootModule,
+				},
+			},
+			Addr: mustResourceInstanceAddr("test_object.foo"),
+		},
+	}
+	diags := node.Execute(ctx, walkPlan)
+	if diags.HasErrors() {
+		t.Fatalf("unexpected error: %s", diags.Err())
+	}
+}