{"record":{"id":"df1d4dc2bc81126e","repo":"hashicorp/terraform","slug":"s-s-must-set-optional-required-or-computed","errorCode":null,"errorMessage":"%s%s: must set Optional, Required or Computed","messagePattern":"(.+?)(.+?): must set Optional, Required or Computed","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/configs/configschema/internal_validate.go","lineNumber":147,"sourceCode":"// schema definitions have any inconsistencies with the documented rules for\n// valid schema.\nfunc (a *Attribute) InternalValidate(name string) error {\n\tif a == nil {\n\t\treturn fmt.Errorf(\"attribute schema is nil\")\n\t}\n\treturn a.internalValidate(name, \"\")\n}\n\nfunc (a *Attribute) internalValidate(name, prefix string) error {\n\tvar err error\n\n\t/* FIXME: this validation breaks certain existing providers and cannot be enforced without coordination.\n\tif !validName.MatchString(name) {\n\t\terr = errors.Join(err, fmt.Errorf(\"%s%s: name may contain only lowercase letters, digits and underscores\", prefix, name))\n\t}\n\t*/\n\tif !a.Optional && !a.Required && !a.Computed {\n\t\terr = errors.Join(err, fmt.Errorf(\"%s%s: must set Optional, Required or Computed\", prefix, name))\n\t}\n\tif a.Optional && a.Required {\n\t\terr = errors.Join(err, fmt.Errorf(\"%s%s: cannot set both Optional and Required\", prefix, name))\n\t}\n\tif a.Computed && a.Required {\n\t\terr = errors.Join(err, fmt.Errorf(\"%s%s: cannot set both Computed and Required\", prefix, name))\n\t}\n\tif !a.Deprecated && a.DeprecationMessage != \"\" {\n\t\terr = errors.Join(err, fmt.Errorf(\"%s%s: DeprecationMessage must not be set when Deprecated is false\", prefix, name))\n\t}\n\n\tif a.Type == cty.NilType && a.NestedType == nil {\n\t\terr = errors.Join(err, fmt.Errorf(\"%s%s: either Type or NestedType must be defined\", prefix, name))\n\t}\n\n\tif a.Type != cty.NilType {\n\t\tif a.NestedType != nil {\n\t\t\terr = errors.Join(fmt.Errorf(\"%s: Type and NestedType cannot both be set\", name))","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/configs/configschema/internal_validate.go#L129-L165","documentation":"Raised when an Attribute has none of Optional, Required, or Computed set. Every attribute must declare its lifecycle so Terraform knows whether the user, the provider, or both supply the value; an undeclared attribute is ambiguous. The check lives at internal_validate.go:146.","triggerScenarios":"An Attribute struct literal with Type set but Optional, Required, and Computed all left as zero-value false. internalValidate at line 138 reaches line 146 and the conjunction is true.","commonSituations":"Adding a new attribute and forgetting its lifecycle flag; relying on a helper that returns an Attribute without setting any flag; migrating from a schema DSL that inferred optionality implicitly.","solutions":["Set exactly one of Optional, Required, or Computed (or Optional+Computed for provider-overridable defaults).","If the attribute is purely informational from the provider, use Computed: true.","Run InternalValidate in provider unit tests so missing flags fail fast."],"exampleFix":"// before\n\"name\": {Type: cty.String},\n\n// after\n\"name\": {Type: cty.String, Optional: true, Computed: true}","handlingStrategy":"validation","validationCode":"func assertAttributeLifecycle(a *configschema.Attribute) error {\n    if !a.Optional && !a.Required && !a.Computed {\n        return fmt.Errorf(\"attribute must set Optional, Required, or Computed\")\n    }\n    return nil\n}","typeGuard":"func hasLifecycleFlag(a *configschema.Attribute) bool {\n    return a.Optional || a.Required || a.Computed\n}","tryCatchPattern":null,"preventionTips":["Always set at least one of Optional/Required/Computed when defining an attribute.","For provider-only output, use Computed; for user input use Optional or Required.","Validate schemas in unit tests so missing flags surface immediately."],"tags":["configschema","attribute","optional","required","computed","validation"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T20:17:04.800Z"}