Repository: opentofu/opentofu
File: internal/tofu/eval_import.go (Go)

Code before:
		return "", diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid import id argument",
			Detail:   "The import ID cannot be null.",
			Subject:  nil,
		})
	}

	// evaluate the import ID and take into consideration the for_each key (if exists)
	importIdVal, evalDiags := evaluateExprWithRepetitionData(context.TODO(), evalCtx, expr, cty.String, keyData)
	diags = diags.Append(evalDiags)

	if importIdVal.IsNull() {
		return "", diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid import id argument",
			Detail:   "The import ID cannot be null.",
			Subject:  expr.Range().Ptr(),
		})
	}

	if !importIdVal.IsKnown() {
		return "", diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid import id argument",
			Detail:   `The import block "id" argument includes an undefined variable or depends on resource attributes that cannot be determined until apply, so OpenTofu cannot plan to import this resource.`, // FIXME and what should I do about that?
			Subject:  expr.Range().Ptr(),
			//	Expression:
			//	EvalContext:
			Extra: evalchecks.DiagnosticCausedByUnknown(true),
		})
	}

	if importIdVal.HasMark(marks.Sensitive) {
		return "", diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid import id argument",
			Detail:   "The import ID cannot be sensitive.",
			Subject:  expr.Range().Ptr(),
		})
	}

	var importId string
	err := gocty.FromCtyValue(importIdVal, &importId)
	if err != nil {
		return "", diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid import id argument",
			Detail:   fmt.Sprintf("The import ID value is unsuitable: %s.", err),
			Subject:  expr.Range().Ptr(),
		})

Review comment (bug):
I would expect an error related to referring to something that hasn't been declared to have already been returned in the `evalDiags` value returned from `evaluateExprWithRepetitionData`, and that diagnostic should have more useful detail about what exactly was wrong.

Assuming that's true, could we instead add a check for whether `evalDiags.HasErrors()` immediately after `diags = diags.Append(evalDiags)` and return early if so? It seems like all of the other checks we perform afterwards are relevant only if the expression was evaluable, and so continuing to make these checks even when expression evaluation failed is likely to generate redundant confusing errors rather than adding additional useful information, and dealing with unknown values here only when the expression was otherwise valid means that we can keep this error message focused only on that one case rather than giving the reader two different possibilities to check. :thinking: 



Code after:
		return "", diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid import id argument",
			Detail:   "The import ID cannot be null.",
			Subject:  nil,
		})
	}

	// evaluate the import ID and take into consideration the for_each key (if exists)
	importIdVal, evalDiags := evaluateExprWithRepetitionData(context.TODO(), evalCtx, expr, cty.String, keyData)
	diags = diags.Append(evalDiags)

	if diags.HasErrors() {
		return "", diags
	}

	if importIdVal.IsNull() {
		return "", diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid import id argument",
			Detail:   "The import ID cannot be null.",
			Subject:  expr.Range().Ptr(),
		})
	}

	if !importIdVal.IsKnown() {
		return "", diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid import id argument",
			Detail:   `The import block "id" argument depends on resource attributes that cannot be determined until apply, so OpenTofu cannot plan to import this resource.`, // FIXME and what should I do about that?
			Subject:  expr.Range().Ptr(),
			//	Expression:
			//	EvalContext:
			Extra: evalchecks.DiagnosticCausedByUnknown(true),
		})
	}

	if importIdVal.HasMark(marks.Sensitive) {
		return "", diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid import id argument",
			Detail:   "The import ID cannot be sensitive.",
			Subject:  expr.Range().Ptr(),
		})
	}

	var importId string
	err := gocty.FromCtyValue(importIdVal, &importId)
	if err != nil {
		return "", diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,