{"record":{"id":"e61d73d0599a03fa","repo":"hashicorp/nomad","slug":"variable-must-not-be-nil","errorCode":null,"errorMessage":"variable must not be nil","messagePattern":"variable must not be nil","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/variables_endpoint.go","lineNumber":78,"sourceCode":"\n// Apply is used to apply a SV update request to the data store.\nfunc (sv *Variables) Apply(args *structs.VariablesApplyRequest, reply *structs.VariablesApplyResponse) error {\n\n\tauthErr := sv.srv.Authenticate(sv.ctx, args)\n\tif done, err := sv.srv.forward(structs.VariablesApplyRPCMethod, args, args, reply); done {\n\t\treturn err\n\t}\n\tsv.srv.MeasureRPCRate(\"variables\", structs.RateMetricWrite, args)\n\tif authErr != nil {\n\t\treturn structs.ErrPermissionDenied\n\t}\n\n\tdefer metrics.MeasureSince([]string{\n\t\t\"nomad\", \"variables\", \"apply\", string(args.Op)}, time.Now())\n\t// TODO: Add metrics for acquire and release if the operation is lock related\n\n\tif args.Var == nil {\n\t\treturn fmt.Errorf(\"variable must not be nil\")\n\t}\n\n\t// Check if the Namespace is explicitly set on the variable. If\n\t// not, use the RequestNamespace\n\ttargetNS := args.Var.Namespace\n\tif targetNS == \"\" {\n\t\ttargetNS = args.RequestNamespace()\n\t\targs.Var.Namespace = targetNS\n\t}\n\n\tif !sv.srv.peersCache.ServersMeetMinimumVersion(sv.srv.Region(), minVersionKeyring, true) {\n\t\treturn fmt.Errorf(\"all servers must be running version %v or later to apply variables\", minVersionKeyring)\n\t}\n\n\t// Perform the ACL resolution.\n\taclObj, err := sv.srv.ResolveACL(args)\n\tif err != nil {\n\t\treturn err","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/variables_endpoint.go#L60-L96","documentation":"Variables.Apply requires the request to carry a Var object describing the variable operation. If args.Var is nil, the endpoint immediately rejects the call before ACL or keyring checks. It is a basic request-shape validation error.","triggerScenarios":"Calling Variables Apply (nomad var put, SDK Apply) with a VariablesApplyRequest whose Var field was never set — e.g. constructing the request for a delete-style op but leaving Var nil.","commonSituations":"Hand-rolling API requests instead of using the CLI/SDK helpers; deserialization dropping the Var field; template code copying a request struct without initializing Var.","solutions":["Populate args.Var with a VariableMetadata/Variable containing path, namespace, and items","Use the nomad CLI (`nomad var put`) or SDK helper which builds Var correctly","Add a nil check on Var before sending the request"],"exampleFix":"// before\nreq := &api.VariablesApplyRequest{Op: api.VarOpSet}\n\n// after\nreq := &api.VariablesApplyRequest{Op: api.VarOpSet,\n    Var: &api.Variable{Path: \"app/config\", Namespace: \"default\", Items: map[string]string{\"k\": \"v\"}}}","handlingStrategy":"validation","validationCode":"if req.Var == nil {\n    return errors.New(\"variables apply request requires a non-nil Var\")\n}\nif req.Var.Path == \"\" {\n    return errors.New(\"variable path is required\")\n}","typeGuard":"func hasVar(r *api.VariablesApplyRequest) bool { return r != nil && r.Var != nil }","tryCatchPattern":"_, err := client.Variables().Apply(req, nil)\nif err != nil && strings.Contains(err.Error(), \"variable must not be nil\") {\n    // fix request construction before retrying\n}","preventionTips":["Construct requests via the CLI/SDK helpers, not raw structs","Nil-check Var (and its Path) before every Apply","Never reuse partially initialized request structs"],"tags":["nomad","variables","validation","nil-value"],"backgroundTag":"missing-required-argument","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"}