{"record":{"id":"66220ae7848fa763","repo":"hashicorp/nomad","slug":"limit-should-be-an-object","errorCode":null,"errorMessage":"limit should be an object","messagePattern":"limit should be an object","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/quota_apply.go","lineNumber":231,"sourceCode":"\t\tif err := hcl.DecodeObject(&m, o.Val); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Manually parse\n\t\tdelete(m, \"region_limit\")\n\n\t\t// Decode the rest\n\t\tvar limit api.QuotaLimit\n\t\tif err := mapstructure.WeakDecode(m, &limit); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// We need this later\n\t\tvar listVal *ast.ObjectList\n\t\tif ot, ok := o.Val.(*ast.ObjectType); ok {\n\t\t\tlistVal = ot.List\n\t\t} else {\n\t\t\treturn fmt.Errorf(\"limit should be an object\")\n\t\t}\n\n\t\t// Parse limits\n\t\tif o := listVal.Filter(\"region_limit\"); len(o.Items) > 0 {\n\t\t\tlimit.RegionLimit = new(api.QuotaResources)\n\t\t\tif err := parseQuotaResource(limit.RegionLimit, o); err != nil {\n\t\t\t\treturn multierror.Prefix(err, \"region_limit ->\")\n\t\t\t}\n\t\t}\n\n\t\t*result = append(*result, &limit)\n\t}\n\n\treturn nil\n}\n\n// parseQuotaResource parses the region_limit resources\nfunc parseQuotaResource(result *api.QuotaResources, list *ast.ObjectList) error {","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/quota_apply.go#L213-L249","documentation":"Within a quota spec, each entry in the limits block must be an object (an HCL ObjectType). parseQuotaLimits walks each limit item; if the item's value is not an object, it cannot extract the inner list and returns this error.","triggerScenarios":"Writing a limit as a scalar or list instead of an object block, e.g. `limit = \"foo\"` or a duplicated key that HCL merges into a non-object value inside `limits {}`.","commonSituations":"Copy-paste mistakes that leave a limit entry with `=` and a string instead of `{ }`, or redeclaring the same limit key causing HCL type conflicts.","solutions":["Define each limit as an object block: `limit { region = \"global\" ... }` inside the `limits` block.","Remove or rename duplicate limit keys so HCL doesn't merge values into a non-object.","Compare against a known-good quota spec example from Nomad docs.","Validate the file with `nomad quota apply -parse-only` to catch structural mistakes early."],"exampleFix":"// before\nlimits {\n  limit = \"global\"\n}\n\n// after\nlimits {\n  limit {\n    region = \"global\"\n  }\n}","handlingStrategy":"validation","validationCode":"// each entry inside limits {} must be an object block\nconst limitBlock = /limits\\s*\\{([^}]*)\\}/s.exec(hcl); \nif (limitBlock && /=\\s*[\"'\\d]/.test(limitBlock[1].replace(/#.*$/gm, ''))) throw new Error('limit entries must be objects: limit { ... }');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always write limits as nested object blocks, never scalars.","Avoid duplicate limit keys that HCL merges into non-object values.","Validate with `nomad quota apply -parse-only` after every edit."],"tags":["hcl","parsing","quota","nomad"],"backgroundTag":"hcl-structure-mismatch","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}