How do I fix a Roster broken by inclusion of a no-longer-existing user?
ERROR [uPortal thread pool worker #227] jasig.portal.[] Jan/09 08:39:47 - net.unicon.sdk.catalog.CatalogException: User does not exist: AndrewPetro net.unicon.sdk.catalog.CatalogException: User does not exist: AndrewPetro at net.unicon.portal.channels.roster.RosterChannel$1 .convertRow(RosterChannel.java:2004) at net.unicon.portal.channels.roster.RosterDbDataSource .fetchData(RosterDbDataSource.java:128) at net.unicon.sdk.catalog.FLazyCatalog.elements(FLazyCatalog.java:139) at net.unicon.portal.channels.roster.RosterChannel .doPageAction(RosterChannel.java:616) at net.unicon.portal.channels.roster.RosterChannel .buildXML(RosterChannel.java:462) at net.unicon.portal.common.AcademusMultithreadedChannel .renderCharacters(AcademusMultithreadedChannel.java:183) at org.jasig.portal.MultithreadedCharacterChannelAdapter .renderCharacters(MultithreadedCharacterChannelAdapter.java:71) at org.jasig.portal.ChannelRenderer$Worker.run(ChannelRenderer.java:483) at org.jasig.portal.utils.threading.Worker.run(Worker.java:88) Caused by: net.unicon.academus.domain.ItemNotFoundException: Can't find user with user_name=AndrewPetro at net.unicon.academus.domain.lms.UserFactory ._getUser(UserFactory.java:483) at net.unicon.academus.domain.lms.UserFactory .getUser(UserFactory.java:448) at net.unicon.portal.channels.roster.RosterChannel$1 .convertRow(RosterChannel.java:2001) ... 8 more ERROR [uPortal thread pool worker #235] jasig.portal.[] Jan/09 08:40:06 - SuperChannel::renderState() : failed to render channel: net.unicon.portal.channels$org.jasig.portal.InternalPortalException at org.jasig.portal.ChannelRenderer .completeRendering(ChannelRenderer.java:330) at net.unicon.portal.util.ChannelRendererWrapper .getResults(ChannelRendererWrapper.java:132) at net.unicon.portal.channels.SuperChannel .renderBuffers(SuperChannel.java:564) at net.unicon.portal.channels.SuperChannel .renderState(SuperChannel.java:253) at net.unicon.portal.channels.SuperChannel .buildXML(SuperChannel.java:217) at net.unicon.portal.channels.LmsChannel .buildXML(LmsChannel.java:305) at net.unicon.portal.common.AcademusMultithreadedChannel .renderCharacters(AcademusMultithreadedChannel.java:183) at org.jasig.portal.MultithreadedCharacterChannelAdapter .renderCharacters(MultithreadedCharacterChannelAdapter.java:71) at org.jasig.portal.ChannelRenderer$Worker.run(ChannelRenderer.java:483) at org.jasig.portal.utils.threading.Worker.run(Worker.java:88)
making it impossible to perform any further updates to that group's enrollments via the web GUI.
This can be solved by directly modifying the Academus database: delete any rows from the 'membership' table that reference the offending user in the 'user_name' column. (Do this carefully, after backing up your data.)
Alternatively, this issue can be addressed through the Academus user interface: create a local-to-the-portal user with a username that matches that of the removed user. This user should then inherit the removed user's enrollments, and an admin should be able to access the roster channel to unenroll them. Once this is done, the portal user may be deleted.
In general it is a best practice to remove a user from Academus via the administrative user interfaces before the user is removed from backing user attribute stores (such as your enterprise LDAP).
Credit is due to Mark Roedel of LeTourneau University for contributing substantively to this knowledge base article.
