{"record":{"id":"6708b4ca0a4e002d","repo":"hashicorp/nomad","slug":"invalid-type-t","errorCode":null,"errorMessage":"invalid type %T","messagePattern":"invalid type %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/quota_apply.go","lineNumber":373,"sourceCode":"\t\tVariablesMB:   variablesLimit,\n\t\tHostVolumesMB: hostVolumesLimit,\n\t}, nil\n}\n\nfunc parseQuotaMegabytes(raw any) (int, error) {\n\tswitch val := raw.(type) {\n\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}","sourceCodeStart":355,"sourceCodeEnd":391,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/quota_apply.go#L355-L391","documentation":"parseQuotaMegabytes only accepts three input types: string (parsed as bytes), int (already in megabytes), and nil (zero). Any other Go type encountered in the quota file — e.g. float64 from JSON decoding, bool, or a list — triggers \"invalid type %T\" naming the offending Go type. It is a structural validation error for quota limit values.","triggerScenarios":"A JSON quota spec sets a limit to 1.5 (float), true, or an array; or an HCL value decodes to a type outside the accepted switch. Values like 500.0 from JSON decoding become float64 and hit this branch.","commonSituations":"Generating quota JSON programmatically and emitting floats or booleans; forgetting quotes on a string with units is fine (string case), but emitting \"host_volumes\": [] or true is not; YAML/JSON round-trips turning ints into floats.","solutions":["Change the value to an unquoted integer (megabytes) or a quoted byte string (\"500MB\").","For JSON, ensure the field is a whole-number JSON int, not a decimal (1.5 -> 1 or use a string with units).","Remove any bool/list/object values from limit fields; quotas accept only a single scalar size.","Check the %T in the message to identify the exact offending type in your file."],"exampleFix":"// before (JSON)\n\"host_volumes\": 1.5\n// after (JSON)\n\"host_volumes\": 500","handlingStrategy":"type-guard","validationCode":"// Ensure the JSON field decodes as int or string before use\nswitch v.(type) {\ncase int, string, nil: // allowed\ndefault:\n    return fmt.Errorf(\"quota limit must be int or string, got %T\", v)\n}","typeGuard":"func isScalarQuotaValue(v any) bool {\n    switch v.(type) {\n    case int, string, nil:\n        return true\n    default:\n        return false\n    }\n}","tryCatchPattern":null,"preventionTips":["When decoding JSON in Go, use json.Number or int types to avoid float64","Never emit decimal, boolean, or array values for quota size fields","Schema-validate generated quota JSON (e.g. with a JSON Schema limiting types)","Beware YAML->JSON converters that turn whole numbers into floats"],"tags":["nomad","type-error","json","quota"],"backgroundTag":"invalid-field-type","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"}