{"record":{"id":"14ff860976259997","repo":"hashicorp/nomad","slug":"only-one-name-may-be-specified","errorCode":null,"errorMessage":"only one name may be specified","messagePattern":"only one name may be specified","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/quota_apply.go","lineNumber":382,"sourceCode":"\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\n\n\t\tvar m map[string]any","sourceCodeStart":364,"sourceCodeEnd":400,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/quota_apply.go#L364-L400","documentation":"Each device entry in a quota spec must have exactly one key (the device name). If an entry has more than one key — e.g. `device \"a\" \"b\" { ... }` — parseDeviceResource rejects it with \"only one name may be specified\", prefixed `resources, device[N]->`. This mirrors the same check Nomad applies to device blocks in job resources.","triggerScenarios":"A quota file declares a device stanza with multiple labels/keys, such as `device \"gpu\" \"tpu\" { }` or a malformed HCL key list on one entry.","commonSituations":"Accidentally specifying two device names in one block instead of two separate device blocks; editor auto-completion duplicating a quoted name; merging two blocks and concatenating their keys.","solutions":["Keep one name per device block and split into separate blocks for multiple devices: `device \"a\" {}` and `device \"b\" {}`.","Use the device[N] prefix in the error to find the offending entry.","Reformat with hclfmt and re-read the stanza to spot duplicated keys.","Validate against Nomad's quota example files."],"exampleFix":"// before\ndevice \"nvidia/gpu\" \"amd/gpu\" {\n  count = 1\n}\n// after\ndevice \"nvidia/gpu\" {\n  count = 1\n}\ndevice \"amd/gpu\" {\n  count = 1\n}","handlingStrategy":"validation","validationCode":"for idx, item := range deviceList.Items {\n    if len(item.Keys) > 1 {\n        return fmt.Errorf(\"resources, device[%d]-> only one name may be specified\", idx)\n    }\n}","typeGuard":"func hasExactlyOneKey(item *hclast.ObjectItem) bool {\n    return item != nil && len(item.Keys) == 1\n}","tryCatchPattern":null,"preventionTips":["One device block per device; never chain multiple quoted names on one stanza","Run hclfmt after editing to expose doubled keys","Review copy-pasted blocks for merged keys","Validate quota files against examples in Nomad docs"],"tags":["nomad","hcl","quota","device"],"backgroundTag":"invalid-block-key-count","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}