{"record":{"id":"d8f52796c09a3ad4","repo":"hashicorp/nomad","slug":"missing-device-name","errorCode":null,"errorMessage":"missing device name","messagePattern":"missing device name","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/quota_apply.go","lineNumber":380,"sourceCode":"\tcase string:\n\t\tb, err := humanize.ParseBytes(val)\n\t\tif err != nil {\n\t\t\treturn 0, fmt.Errorf(\"could not parse value as bytes: %v\", err)\n\t\t}\n\t\treturn int(b >> 20), nil\n\tcase int:\n\t\treturn val, nil\n\tcase nil:\n\t\treturn 0, nil\n\tdefault:\n\t\treturn 0, fmt.Errorf(\"invalid type %T\", raw)\n\t}\n}\n\nfunc parseDeviceResource(result *[]*api.RequestedDevice, list *ast.ObjectList) error {\n\tfor idx, o := range list.Items {\n\t\tif l := len(o.Keys); l == 0 {\n\t\t\treturn multierror.Prefix(fmt.Errorf(\"missing device name\"), fmt.Sprintf(\"resources, device[%d]->\", idx))\n\t\t} else if l > 1 {\n\t\t\treturn multierror.Prefix(fmt.Errorf(\"only one name may be specified\"), fmt.Sprintf(\"resources, device[%d]->\", idx))\n\t\t}\n\n\t\tname := o.Keys[0].Token.Value().(string)\n\n\t\t// Check for invalid keys\n\t\tvalid := []string{\n\t\t\t\"name\",\n\t\t\t\"count\",\n\t\t}\n\t\tif err := helper.CheckHCLKeys(o.Val, valid); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Set the name\n\t\tvar device api.RequestedDevice\n\t\tdevice.Name = name","sourceCodeStart":362,"sourceCodeEnd":398,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/quota_apply.go#L362-L398","documentation":"In parseDeviceResource each item of the quota's `device` block must be a keyed entry where the key is the device name. An entry with zero keys (e.g. a bare block with no name) produces \"missing device name\", prefixed as `resources, device[N]->` so the index of the offending entry is known. It is HCL structure validation for `nomad quota apply`.","triggerScenarios":"A quota file contains a device entry written without a name key, e.g. an anonymous `device { ... }` block or a list element missing its label, inside the resources stanza of the quota spec.","commonSituations":"Copy-pasting job-spec device syntax into a quota file where a named key is required; hand-editing HCL and deleting the name by accident; converting JSON to HCL and dropping the object key.","solutions":["Give every device entry exactly one name key, e.g. `device \"nvidia/gpu\" { count = 2 }`.","Locate the entry via the `device[N]` prefix in the error (zero-based index) and fix that specific stanza.","Compare against valid quota examples in the Nomad docs for the device block syntax.","Run the file through HCL validation (`hclfmt`/lint) to catch anonymous blocks."],"exampleFix":"// before\ndevice {\n  count = 1\n}\n// after\ndevice \"nvidia/gpu\" {\n  count = 1\n}","handlingStrategy":"validation","validationCode":"// Check every device entry has exactly one key before parsing\nfor idx, item := range deviceList.Items {\n    if len(item.Keys) == 0 {\n        return fmt.Errorf(\"resources, device[%d]-> missing device name\", idx)\n    }\n}","typeGuard":"func hasNameKey(item *hclast.ObjectItem) bool {\n    return item != nil && len(item.Keys) == 1\n}","tryCatchPattern":null,"preventionTips":["Always write device entries as named blocks: device \"vendor/model\" { ... }","Run hclfmt/hcl lint on quota files in CI","Don't copy anonymous block syntax from job files into quota specs","Index error prefixes (device[N]) map to file order — keep entries small and labeled"],"tags":["nomad","hcl","quota","device"],"backgroundTag":"missing-block-name","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"}