{"record":{"id":"370e4d21431e4d3c","repo":"OpenNHP/opennhp","slug":"aspid-or-resid-is-empty","errorCode":null,"errorMessage":"aspId or resId is empty","messagePattern":"aspId or resId is empty","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"endpoints/server/udpserver.go","lineNumber":1110,"sourceCode":"\ts.authServiceMap[aspData.AuthSvcId] = aspData\n\ts.authServiceMapMutex.Unlock()\n\n\tif len(aspData.PluginPath) > 0 {\n\t\th := plugins.ReadPluginHandler(aspData.PluginPath)\n\t\tif h != nil {\n\t\t\terr := s.LoadPlugin(aspData.AuthSvcId, h)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (s *UdpServer) AddResource(res *common.ResourceData) error {\n\tif len(res.AuthServiceId) == 0 || len(res.ResourceId) == 0 {\n\t\treturn fmt.Errorf(\"aspId or resId is empty\")\n\t}\n\n\ts.authServiceMapMutex.Lock()\n\taspData, found := s.authServiceMap[res.AuthServiceId]\n\tif !found {\n\t\ts.authServiceMapMutex.Unlock()\n\t\treturn fmt.Errorf(\"aspId not found\")\n\t}\n\taspData.ResourceGroups[res.ResourceId] = res\n\ts.authServiceMapMutex.Unlock()\n\n\treturn nil\n}\n\nfunc (s *UdpServer) ValidatePlugin(h plugins.PluginHandler) bool {\n\t// placeholder to validate plugin file\n\t// err = checkSignature(s.Signature())\n\t// if err != nil {","sourceCodeStart":1092,"sourceCodeEnd":1128,"githubUrl":"https://github.com/OpenNHP/opennhp/blob/6e04ca5ff03222a699c24205cd4bf8fee9af7ffe/endpoints/server/udpserver.go#L1092-L1128","documentation":"AddResource requires both ResourceData.AuthServiceId (which ASP owns it) and ResourceData.ResourceId (its key in the ASP's ResourceGroups map). If either string is empty the resource cannot be filed, so it is rejected up front.","triggerScenarios":"Calling UdpServer.AddResource with a *common.ResourceData where AuthServiceId == \"\" or ResourceId == \"\".","commonSituations":"TOML resource entries missing the resourceId key; plugins building ResourceData from partial JSON where one field is absent; renaming a resource field in config and not updating the loader mapping.","solutions":["Populate both AuthServiceId and ResourceId on the ResourceData before the call","Fix the resource.toml entry so both fields are present and non-empty","Validate the ResourceData at construction time and skip/defect log invalid entries"],"exampleFix":"// before\nsrv.AddResource(&common.ResourceData{AuthServiceId: \"asp-1\"})\n// after\nsrv.AddResource(&common.ResourceData{AuthServiceId: \"asp-1\", ResourceId: \"web-portal\"})","handlingStrategy":"validation","validationCode":"func validResource(r *common.ResourceData) bool {\n    return r != nil && r.AuthServiceId != \"\" && r.ResourceId != \"\"\n}\nif !validResource(res) { return errors.New(\"resource needs AuthServiceId and ResourceId\") }\nerr := srv.AddResource(res)","typeGuard":"func resourceIsComplete(r *common.ResourceData) bool { return r != nil && len(r.AuthServiceId) > 0 && len(r.ResourceId) > 0 }","tryCatchPattern":"if err := srv.AddResource(res); err != nil {\n    return fmt.Errorf(\"AddResource(asp=%q, res=%q): %w\", res.AuthServiceId, res.ResourceId, err)\n}","preventionTips":["Validate ResourceData immediately after config decode","Keep resource.toml field names in sync with the ResourceData struct","Fail the deploy if any resource entry lacks either id"],"tags":["validation","config"],"backgroundTag":"empty-required-field","analyzedSha":"6e04ca5ff03222a699c24205cd4bf8fee9af7ffe","analyzedAt":"2026-09-07T15:44:59.941Z","contentChangedAt":"2026-09-07T15:44:59.941Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}