{"record":{"id":"9f24e227dba01df3","repo":"hashicorp/nomad","slug":"claim-allocationid-is-required","errorCode":null,"errorMessage":"Claim.AllocationID is required","messagePattern":"Claim\\.AllocationID is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/structs/csi.go","lineNumber":492,"sourceCode":"}\n\nfunc (req *ClientCSINodeExpandVolumeRequest) Validate() error {\n\tvar err error\n\t// These should not occur during normal operations; they're here\n\t// mainly to catch potential programmer error.\n\tif req.PluginID == \"\" {\n\t\terr = errors.Join(err, errors.New(\"PluginID is required\"))\n\t}\n\tif req.VolumeID == \"\" {\n\t\terr = errors.Join(err, errors.New(\"VolumeID is required\"))\n\t}\n\tif req.ExternalID == \"\" {\n\t\terr = errors.Join(err, errors.New(\"ExternalID is required\"))\n\t}\n\tif req.Claim == nil {\n\t\terr = errors.Join(err, errors.New(\"Claim is required\"))\n\t} else if req.Claim.AllocationID == \"\" {\n\t\terr = errors.Join(err, errors.New(\"Claim.AllocationID is required\"))\n\t}\n\treturn err\n}\n\ntype ClientCSINodeExpandVolumeResponse struct {\n\tCapacityBytes int64\n}\n","sourceCodeStart":474,"sourceCodeEnd":500,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/structs/csi.go#L474-L500","documentation":"Produced by ClientCSINodeExpandVolumeRequest.Validate() in client/structs/csi.go when req.Claim is non-nil but Claim.AllocationID is empty. Like the sibling checks, it exists to catch programmer error: every CSI volume claim must reference the allocation that holds it. It is joined with other validation errors via errors.Join.","triggerScenarios":"Calling the CSI NodeExpandVolume client RPC with a Claim struct that was partially initialized — e.g. &CSIVolumeClaim{NodeID: ..., Mode: ...} — but where AllocationID was never set.","commonSituations":"Hand-constructed requests in tests or tooling; code that builds a claim from a partially-deserialized state where the allocation ID was lost; custom scheduler or plugin code deriving claims without an alloc context.","solutions":["Set Claim.AllocationID to the ID of the allocation using the volume before validating","Verify the claim object was hydrated from the server's CSIVolumeClaim state, not an empty stub","Run Validate() only after the full claim lifecycle fields (AllocationID, NodeID, Mode) are populated"],"exampleFix":"// before\nclaim := &cstructs.CSIVolumeClaim{NodeID: nodeID, Mode: structs.CSIVolumeClaimMode}\n// after\nclaim := &cstructs.CSIVolumeClaim{AllocationID: alloc.ID, NodeID: nodeID, Mode: structs.CSIVolumeClaimMode}","handlingStrategy":"validation","validationCode":"if req.Claim == nil || req.Claim.AllocationID == \"\" {\n\treturn fmt.Errorf(\"node expand requires a claim with AllocationID\")\n}","typeGuard":"func claimHasAllocation(c *structs.CSIVolumeClaim) bool {\n\treturn c != nil && c.AllocationID != \"\"\n}","tryCatchPattern":"if err := req.Validate(); err != nil {\n\tif strings.Contains(err.Error(), \"Claim.AllocationID is required\") {\n\t\treq.Claim.AllocationID = alloc.ID\n\t}\n\treturn err\n}","preventionTips":["Populate AllocationID at claim construction time, never as a later patch","Use constructor helpers that take alloc.ID so the field cannot be skipped","Add tests asserting Claim.AllocationID != \"\" before RPC dispatch"],"tags":["csi","validation","nomad","storage"],"backgroundTag":"csi-request-validation-failed","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"}