{"record":{"id":"9ec8ae085726fa69","repo":"hashicorp/terraform","slug":"s-s-minitems-must-be-less-than-or-equal-to-maxit","errorCode":null,"errorMessage":"%s%s: MinItems must be less than or equal to MaxItems in %s mode","messagePattern":"(.+?)(.+?): MinItems must be less than or equal to MaxItems in (.+?) mode","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/configs/configschema/internal_validate.go","lineNumber":90,"sourceCode":"\n\t\tswitch blockS.Nesting {\n\t\tcase NestingSingle:\n\t\t\tswitch {\n\t\t\tcase blockS.MinItems != blockS.MaxItems:\n\t\t\t\tmultiErr = errors.Join(multiErr, fmt.Errorf(\"%s%s: MinItems and MaxItems must match in NestingSingle mode\", prefix, name))\n\t\t\tcase blockS.MinItems < 0 || blockS.MinItems > 1:\n\t\t\t\tmultiErr = errors.Join(multiErr, fmt.Errorf(\"%s%s: MinItems and MaxItems must be set to either 0 or 1 in NestingSingle mode\", prefix, name))\n\t\t\t}\n\t\tcase NestingGroup:\n\t\t\tif blockS.MinItems != 0 || blockS.MaxItems != 0 {\n\t\t\t\tmultiErr = errors.Join(multiErr, fmt.Errorf(\"%s%s: MinItems and MaxItems cannot be used in NestingGroup mode\", prefix, name))\n\t\t\t}\n\t\t\tif blockS.Computed {\n\t\t\t\tmultiErr = errors.Join(multiErr, fmt.Errorf(\"%s%s: NestingGroup blocks cannot be computed\", prefix, name))\n\t\t\t}\n\t\tcase NestingList, NestingSet:\n\t\t\tif blockS.MinItems > blockS.MaxItems && blockS.MaxItems != 0 {\n\t\t\t\tmultiErr = errors.Join(multiErr, fmt.Errorf(\"%s%s: MinItems must be less than or equal to MaxItems in %s mode\", prefix, name, blockS.Nesting))\n\t\t\t}\n\t\t\tif blockS.Nesting == NestingSet {\n\t\t\t\tety := blockS.Block.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\n\t\t\t\t\t// properly hash them, and so can't support mixed types.\n\t\t\t\t\tmultiErr = errors.Join(multiErr, fmt.Errorf(\"%s%s: NestingSet blocks may not contain attributes of cty.DynamicPseudoType\", prefix, name))\n\t\t\t\t}\n\t\t\t\tif blockS.Block.ContainsWriteOnly() {\n\t\t\t\t\t// This is not permitted because any marks within sets will\n\t\t\t\t\t// be hoisted up the outer set value, so only the set itself\n\t\t\t\t\t// can be WriteOnly.\n\t\t\t\t\tmultiErr = errors.Join(multiErr, fmt.Errorf(\"%s%s: NestingSet blocks may not contain WriteOnly attributes\", prefix, name))\n\t\t\t\t}\n\t\t\t}\n\t\t\tif blockS.MinItems > 0 && blockS.Computed {\n\t\t\t\tmultiErr = errors.Join(multiErr, fmt.Errorf(\"%s%s: Computed cannot be used when MinItems > 0\", prefix, name))","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/configs/configschema/internal_validate.go#L72-L108","documentation":"Raised for NestingList or NestingSet blocks when MinItems exceeds MaxItems and MaxItems is non-zero. Cardinality bounds must form a valid range; an inverted range is a logical impossibility the validator refuses to serialize. The check lives at internal_validate.go:89 and includes the offending nesting mode in the message so the developer knows which block type tripped it.","triggerScenarios":"A NestedBlock with Nesting=NestingList (or NestingSet) where MinItems > MaxItems and MaxItems != 0 — e.g. MinItems: 5, MaxItems: 3. The validator enters the NestingList/NestingSet case at line 88 and fails the condition at line 89.","commonSituations":"Editing cardinality constants and swapping min/max values by mistake; generating schemas from a DSL where the lower/upper bounds were mapped to the wrong fields; copy-pasting a block and decrementing MaxItems below an inherited MinItems.","solutions":["Set MinItems to a value less than or equal to MaxItems (or set both to 0 for an unbounded list).","If you intended a required minimum with no upper bound, leave MaxItems at 0 — the validator treats 0 as 'no upper limit'.","Add a unit test that calls InternalValidate on the provider schema to catch inverted bounds before release."],"exampleFix":"// before\n&NestedBlock{Nesting: NestingList, MinItems: 5, MaxItems: 3}\n\n// after\n&NestedBlock{Nesting: NestingList, MinItems: 3, MaxItems: 5}","handlingStrategy":"validation","validationCode":"func assertCardinality(nb *configschema.NestedBlock) error {\n    if nb.MinItems > nb.MaxItems && nb.MaxItems != 0 {\n        return fmt.Errorf(\"MinItems (%d) must be <= MaxItems (%d)\", nb.MinItems, nb.MaxItems)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat MinItems/MaxItems as a pair: define them together in a helper that validates min<=max.","Remember MaxItems==0 means 'no upper bound', not 'zero allowed' — use it for unbounded lists.","Run InternalValidate in CI to catch inverted bounds before merge."],"tags":["configschema","nesting-list","nesting-set","minitems","maxitems","validation"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T20:17:04.800Z"}