{"record":{"id":"5629dde9772e8254","repo":"hashicorp/nomad","slug":"must-specify-plugin-allocation-id-to-deregister","errorCode":null,"errorMessage":"must specify plugin allocation ID to deregister","messagePattern":"must specify plugin allocation ID to deregister","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/dynamicplugins/registry.go","lineNumber":255,"sourceCode":"\treturn broadcaster\n}\n\nfunc (d *dynamicRegistry) DeregisterPlugin(ptype, name, allocID string) error {\n\td.pluginsLock.Lock()\n\tdefer d.pluginsLock.Unlock()\n\n\tif ptype == \"\" {\n\t\t// This error shouldn't make it to a production cluster and is to aid\n\t\t// developers during the development of new plugin types.\n\t\treturn errors.New(\"must specify plugin type to deregister\")\n\t}\n\tif name == \"\" {\n\t\t// This error shouldn't make it to a production cluster and is to aid\n\t\t// developers during the development of new plugin types.\n\t\treturn errors.New(\"must specify plugin name to deregister\")\n\t}\n\tif allocID == \"\" {\n\t\treturn errors.New(\"must specify plugin allocation ID to deregister\")\n\t}\n\n\tpmap, ok := d.plugins[ptype]\n\tif !ok {\n\t\t// If this occurs there's a bug in the registration handler.\n\t\treturn fmt.Errorf(\"no plugins registered for type: %s\", ptype)\n\t}\n\n\tinfos, ok := pmap[name]\n\tif !ok {\n\t\t// plugin already deregistered, don't send events or try re-deleting.\n\t\treturn nil\n\t}\n\n\tvar info *PluginInfo\n\tfor e := infos.Front(); e != nil; e = e.Next() {\n\t\tinfo = e.Value.(*PluginInfo)\n\t\tif info.AllocID == allocID {","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/dynamicplugins/registry.go#L237-L273","documentation":"DeregisterPlugin tracks which allocation (allocID) holds the plugin registration so usage can be reference-counted. An empty allocID prevents the registry from updating the per-allocation registration correctly, so it is rejected.","triggerScenarios":"Calling Registry.DeregisterPlugin(ptype, name, \"\") with an empty allocation ID, typically in client alloc teardown when the allocation ID was not propagated to the plugin cleanup code.","commonSituations":"Running plugin deregistration outside a normal alloc lifecycle (manual cleanup, tests), or alloc restore paths where the allocID field is empty.","solutions":["Pass the alloc.ID of the allocation that registered the plugin","Validate allocID is non-empty before calling DeregisterPlugin","Check that the deregistering code path has access to the alloc state and is not invoked with a nil/partial alloc"],"exampleFix":"// before\nerr := registry.DeregisterPlugin(ptype, name, \"\")\n// after\nif allocID == \"\" {\n    return fmt.Errorf(\"cannot deregister plugin %s/%s: empty alloc ID\", ptype, name)\n}\nerr := registry.DeregisterPlugin(ptype, name, allocID)","handlingStrategy":"validation","validationCode":"if allocID == \"\" {\n    return fmt.Errorf(\"deregister: alloc ID is required\")\n}\nerr := registry.DeregisterPlugin(ptype, name, allocID)","typeGuard":"func canDeregister(ptype, name, allocID string) bool {\n    return ptype != \"\" && name != \"\" && allocID != \"\"\n}","tryCatchPattern":"err := registry.DeregisterPlugin(ptype, name, allocID)\nif err != nil {\n    if strings.Contains(err.Error(), \"must specify plugin allocation ID\") {\n        return fmt.Errorf(\"alloc %q deregistration of plugin %s/%s missing alloc ID: %w\", allocID, ptype, name, err)\n    }\n    return err\n}","preventionTips":["Ensure deregistration is only invoked with a valid alloc state (non-empty alloc.ID)","Avoid invoking plugin deregistration outside the alloc lifecycle helpers","Log allocID at deregistration call sites to catch empty values early"],"tags":["validation","plugin-registry","nomad"],"backgroundTag":"empty-required-field","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"}