{"record":{"id":"11d4b1feb22ec6a8","repo":"hashicorp/terraform","slug":"object-schema-nesting-mode-is-invalid","errorCode":null,"errorMessage":"object schema nesting mode is invalid","messagePattern":"object schema nesting mode is invalid","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/configs/configschema/internal_validate.go","lineNumber":208,"sourceCode":"\t\t\terr = errors.Join(err, fmt.Errorf(\"%s%s: invalid nesting mode %s\", prefix, name, a.NestedType.Nesting))\n\t\t}\n\t\tfor name, attrS := range a.NestedType.Attributes {\n\t\t\tif attrS == nil {\n\t\t\t\terr = errors.Join(err, fmt.Errorf(\"%s%s: attribute schema is nil\", prefix, name))\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\terr = errors.Join(err, attrS.internalValidate(name, prefix))\n\t\t}\n\t}\n\n\treturn err\n}\n\nfunc (o *Object) InternalValidate() error {\n\tvar err error\n\n\tif o.Nesting == nestingModeInvalid {\n\t\treturn fmt.Errorf(\"object schema nesting mode is invalid\")\n\t}\n\n\tfor name, attrS := range o.Attributes {\n\t\tif attrS == nil {\n\t\t\terr = errors.Join(err, fmt.Errorf(\"%s: attribute schema is nil\", name))\n\t\t\tcontinue\n\t\t}\n\t\terr = errors.Join(err, attrS.internalValidate(name, \"\"))\n\t}\n\n\treturn err\n}\n","sourceCodeStart":190,"sourceCodeEnd":221,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/configs/configschema/internal_validate.go#L190-L221","documentation":"Returned by Object.InternalValidate when the Object's Nesting field equals the sentinel nestingModeInvalid. This is the top-level guard before any attribute recursion — it short-circuits because every other operation on the Object assumes a valid nesting mode. As with [843], this is a schema-construction defect, not a user-input issue.","triggerScenarios":"Constructing a *configschema.Object (e.g. as the schema for a Block or a top-level resource schema) without setting Nesting, then calling InternalValidate. nestingModeInvalid is the zero/sentinel value used to flag 'unset'.","commonSituations":"Hand-rolled schema literals in provider tests; deserializing a schema from an older format that did not carry a Nesting field; refactoring that introduces nestingModeInvalid as a default but forgets to overwrite it before validation.","solutions":["Set Object.Nesting to a valid mode (typically NestingSingle for a resource's top-level block) before calling InternalValidate.","If the Object is built by a factory, fail construction early when Nesting is nestingModeInvalid instead of letting InternalValidate surface it.","Add a constructor (NewObject(nestingMode)) so an unset mode is impossible at the type level."],"exampleFix":"// before\nobj := &configschema.Object{Attributes: attrs}\n\n// after\nobj := &configschema.Object{Nesting: configschema.NestingSingle, Attributes: attrs}","handlingStrategy":"validation","validationCode":"func assertObjectNestingValid(o *configschema.Object) error {\n    if o == nil { return fmt.Errorf(\"nil object schema\") }\n    if o.Nesting == configschema.nestingModeInvalid { // or zero value depending on pkg\n        return fmt.Errorf(\"object nesting mode is invalid/unset\")\n    }\n    return nil\n}","typeGuard":"func isObjectNestingSet(o *configschema.Object) bool {\n    return o != nil && o.Nesting != configschema.nestingModeInvalid\n}","tryCatchPattern":null,"preventionTips":["Construct Objects via a factory that mandates a Nesting argument.","Treat the zero value of Nesting as a programmer error to be caught in tests.","Validate the schema tree once at provider startup, not per-request."],"tags":["schema-validation","configschema","nesting-mode","go"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}