{"record":{"id":"dfd1bcfe8dbac7fd","repo":"hashicorp/terraform","slug":"top-level-block-schema-is-nil","errorCode":null,"errorMessage":"top-level block schema is nil","messagePattern":"top-level block schema is nil","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/configs/configschema/internal_validate.go","lineNumber":24,"sourceCode":"import (\n\t\"errors\"\n\t\"fmt\"\n\t\"regexp\"\n\n\t\"github.com/zclconf/go-cty/cty\"\n)\n\nvar validName = regexp.MustCompile(`^[a-z0-9_]+$`)\n\n// InternalValidate returns an error if the receiving block and its child schema\n// definitions have any inconsistencies with the documented rules for valid\n// schema.\n//\n// This can be used within unit tests to detect when a given schema is invalid,\n// and is run when terraform loads provider schemas during NewContext.\nfunc (b *Block) InternalValidate() error {\n\tif b == nil {\n\t\treturn fmt.Errorf(\"top-level block schema is nil\")\n\t}\n\treturn b.internalValidate(\"\")\n}\n\nfunc (b *Block) internalValidate(prefix string) error {\n\tvar multiErr error\n\n\tif prefix == \"\" && !b.Deprecated && b.DeprecationMessage != \"\" {\n\t\tmultiErr = errors.Join(multiErr, fmt.Errorf(\"top-level block: DeprecationMessage must not be set when Deprecated is false\"))\n\t}\n\n\tfor name, attrS := range b.Attributes {\n\t\tif attrS == nil {\n\t\t\tmultiErr = errors.Join(multiErr, fmt.Errorf(\"%s%s: attribute schema is nil\", prefix, name))\n\t\t\tcontinue\n\t\t}\n\t\tmultiErr = errors.Join(multiErr, attrS.internalValidate(name, prefix))\n","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/configs/configschema/internal_validate.go#L6-L42","documentation":"InternalValidate returns this when the receiver Block pointer itself is nil. It is the first guard in Block.InternalValidate() (line 23): a nil top-level schema has nothing to validate, so it fails immediately. This is a provider/schema-author programming error, surfaced in unit tests or during schema loading in NewContext.","triggerScenarios":"Calling (*Block)(nil).InternalValidate(), or a schema map field pointing to an uninitialized *Block. Typically a missing return/initialization in provider GetSchemaResponse, or a test that declares `var schema *configschema.Block` and validates it.","commonSituations":"New resource/data-source schema left nil, a refactor that returns nil before assigning the schema, schema tables built conditionally where a branch returns nil.","solutions":["Ensure the Block is allocated before validation: `schema := &configschema.Block{...}`.","If nil is legitimately possible, guard before calling InternalValidate: `if schema != nil { ... }`.","Add a unit test that calls InternalValidate on every exported schema so this is caught in CI."],"exampleFix":"// before\nvar schema *configschema.Block\nif err := schema.InternalValidate(); err != nil { t.Fatal(err) }\n\n// after\nschema := &configschema.Block{\n    Attributes: map[string]*configschema.Attribute{\n        \"name\": {Type: cty.String, Optional: true, Computed: true},\n    },\n}\nif err := schema.InternalValidate(); err != nil { t.Fatal(err) }","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// Guard against a nil schema before validating.\nfunc schemaValid(b *configschema.Block) error {\n    if b == nil { return errors.New(\"schema Block must be non-nil\") }\n    return b.InternalValidate()\n}","tryCatchPattern":null,"preventionTips":["Always allocate schema literals with &configschema.Block{}; never leave a *Block as its zero (nil) value.","Run InternalValidate in a table test covering every resource/data-source schema."],"tags":["configschema","provider-sdk","validation","nil-pointer"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T20:17:04.800Z"}