{"record":{"id":"4c0a607db66f107f","repo":"hashicorp/terraform","slug":"s-s-either-type-or-nestedtype-must-be-defined","errorCode":null,"errorMessage":"%s%s: either Type or NestedType must be defined","messagePattern":"(.+?)(.+?): either Type or NestedType must be defined","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/configs/configschema/internal_validate.go","lineNumber":160,"sourceCode":"\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))\n\t\t}\n\t}\n\n\tif a.NestedType != nil {\n\t\tswitch a.NestedType.Nesting {\n\t\tcase NestingSingle, NestingMap, NestingGroup:\n\t\t\t// no validations to perform\n\t\tcase NestingList, NestingSet:\n\t\t\tif a.NestedType.Nesting == NestingSet {\n\t\t\t\tety := a.ImpliedType()\n\t\t\t\tif ety.HasDynamicTypes() {\n\t\t\t\t\t// This is not permitted because the HCL (cty) set implementation\n\t\t\t\t\t// needs to know the exact type of set elements in order to","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/configs/configschema/internal_validate.go#L142-L178","documentation":"Raised when an Attribute has neither Type nor NestedType set. Every attribute must carry a type — either a flat cty.Type or a structural *Object via NestedType; an attribute with neither has no representable value. The check at internal_validate.go:159 tests for Type==cty.NilType && NestedType==nil.","triggerScenarios":"An Attribute struct literal with Optional: true but no Type or NestedType field. internalValidate reaches line 159 and the conjunction is true.","commonSituations":"Adding an attribute and forgetting its type; refactoring that moved the type into a helper returning the zero Type; copy-pasting a placeholder attribute that was never filled in.","solutions":["Set Type to a concrete cty type (e.g. cty.String, cty.List(cty.Number)).","If the attribute is a structural object, set NestedType to a populated *Object with a NestingMode.","Validate schemas in unit tests so untyped attributes fail immediately."],"exampleFix":"// before\n\"name\": {Optional: true},\n\n// after\n\"name\": {Type: cty.String, Optional: true}","handlingStrategy":"validation","validationCode":"func assertHasType(a *configschema.Attribute) error {\n    if a.Type == cty.NilType && a.NestedType == nil {\n        return fmt.Errorf(\"attribute must define Type or NestedType\")\n    }\n    return nil\n}","typeGuard":"func hasTypeOrNestedType(a *configschema.Attribute) bool {\n    return a.Type != cty.NilType || a.NestedType != nil\n}","tryCatchPattern":null,"preventionTips":["Every attribute needs exactly one type representation: flat Type or structural NestedType.","Define attributes via helpers that require a type parameter, so untyped literals cannot be expressed.","Run InternalValidate in tests to catch missing types early."],"tags":["configschema","attribute","type","nestedtype","validation"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}