Passed List Had More than One Value when Calling Dashboard

Still need help?

The Atlassian Community is here for you.

Ask the community

Symptoms

Symptom 1

Users trying to access the dashboard will encounter a System Error page containing an exception like:

java.lang.IllegalArgumentException: Passed List had more than one value.
at org.ofbiz.core.entity.EntityUtil.getOnly(EntityUtil.java:58)
at com.atlassian.jira.portal.OfBizPortalPageStore.getPortalPageByOwnerAndName(OfBizPortalPageStore.java:135)
at com.atlassian.jira.portal.CachingPortalPageStore.getPortalPageByOwnerAndName(CachingPortalPageStore.java:160)
at com.atlassian.jira.portal.DefaultPortalPageManager.getPortalPageByName(DefaultPortalPageManager.java:152)
at com.atlassian.jira.bc.portal.AbstractPortalPageService.validateForUpdate(AbstractPortalPageService.java:401)
at com.atlassian.jira.dashboard.permission.JiraPermissionService.isWritableBy(JiraPermissionService.java:63)
at com.atlassian.jira.dashboard.permission.JiraGadgetPermissionManager.filterGadgets(JiraGadgetPermissionManager.java:54)
...

or Application logs also contain the following ERROR report:

...
Exception caught in 500 page Passed List had more than one value.
java.lang.IllegalArgumentException: Passed List had more than one value.
	at org.ofbiz.core.entity.EntityUtil.getOnly(EntityUtil.java:58)
	at com.atlassian.jira.portal.OfBizPortalPageStore.getPortalPageByOwnerAndName(OfBizPortalPageStore.java:135)
	at com.atlassian.jira.portal.CachingPortalPageStore.getPortalPageByOwnerAndName(CachingPortalPageStore.java:160)
...

Symptom 2

Users are trying to access Jira or load the System dashboard, they are possibly presented with an HTTP 500 error and the following exception is present in the application log:

Servlet.service() for servlet [action] threw exception
java.lang.IllegalArgumentException: Passed List had more than one value.
        at org.ofbiz.core.entity.EntityUtil.getOnly(EntityUtil.java:68)
        at com.atlassian.jira.portal.OfBizPortalPageStore.getSystemDefaultPortalPage(OfBizPortalPageStore.java:197)
        at com.atlassian.jira.portal.CachingPortalPageStore.getSystemDefaultPortalPage(CachingPortalPageStore.java:86)
        at com.atlassian.jira.portal.DefaultPortalPageManager.getSystemDefaultPortalPage(DefaultPortalPageManager.java:154)
        at com.atlassian.jira.bc.portal.DefaultPortalPageService.getSystemDefaultPortalPage(DefaultPortalPageService.java:159)
        at com.atlassian.jira.web.action.Dashboard.getPageIdForUser(Dashboard.java:574)
        at com.atlassian.jira.web.action.Dashboard.initialiseCurrentDashboardId(Dashboard.java:536)
        at com.atlassian.jira.web.action.Dashboard.getCurrentDashboardId(Dashboard.java:246)
        at com.atlassian.jira.web.action.Dashboard.getCurrentDashboardState(Dashboard.java:259)
        at com.atlassian.jira.web.action.Dashboard.doValidation(Dashboard.java:154)
        ... 2 filtered

Diagnoses

Diagnosis 1

Further proof can be determined with the following query, which should return the username of the dashboard owner and the dashboard name for the affected dashboards:

SELECT username, pagename, count(pagename) FROM portalpage GROUP BY username,pagename HAVING count(pagename) > 1;

Diagnosis 2

There could be multiple unowned dashboards, i.e. where the username is set to null, run the following to see if you have this problem:

SELECT * FROM portalpage WHERE username IS NULL; 

If the above query returns more than one row, you're affected by this problem - please refer to Resolution 2 below.

Causes

The portalpage table is used to store users' dashboards. Normally, it should contain one different pagename for each user. It should not contain names of duplicated pages per user, nor should it contain null for any dashboards other than the 'System dashboard'. If there are duplicates or dashboards not with a valid username, the "Passed List had more than one value" exception will occur.

Here is the code from OfBizPortalPageStore, where the application is expecting a single value from the underlying database:

final GenericValue pageGV = EntityUtil.getOnly(delegator.findByAnd(Table.NAME, EasyMap.build(Column.USERNAME, owner.getName(), Column.PAGENAME, name), DEFAULT_ORDER_BY_CLAUSE));

Resolution

Resolution 1 - for Diagnosis 1

Remove the duplicate tuples from the portalpage table by using the username and pagename column. Use the diagnosis section above for reference. For example:

Always back up your data before performing any modification to the database. If possible, try your modifications on a test server.

METHOD 1 - for Resolution 1
  1. Running the below query will provide all the duplicated entries with their ids:

    select username,id from portalpage where username in (SELECT username FROM portalpage GROUP BY username,pagename HAVING count(pagename) > 1)
  2. Delete all the rows except one row for each of those users using the ID of the row.
METHOD 2 - for Resolution 1

Run the below SQL for a direct deletion of all the duplicated rows. This has been tested only on PostgreSQL:

DELETE
FROM portalpage p1 USING
  (SELECT username,
          id
   FROM portalpage
   WHERE username IN
       (SELECT username
        FROM portalpage
        GROUP BY username,
                 pagename HAVING count(pagename) > 1)) p2,
  (SELECT username,
          max(id) maxid
   FROM portalpage
   WHERE username IN
       (SELECT username
        FROM portalpage
        GROUP BY username,
                 pagename HAVING count(pagename) > 1)
   GROUP BY username) p3
WHERE p1.username = p2.username
  AND p3.maxid != p1.id
  AND p3.username = p2.username;

Resolution 2 - for Diagnosis 2

First, choose one of the dashboards returned by the query in Diagnosis 2 to be the default dashboard (usually this will be the built-in default dashboard with ID 10000), then choose a user account to be the new owner of the other dashboards.

Next, update the other dashboards using the SQL query below, replacing <new_owner_username> with the username of the chosen user account and <default_dashboard_id> with the ID of the default dashboard (you can obtain this from the results of the query in Diagnosis 2):

UPDATE portalpage SET username = '<new_owner_username>' WHERE id IN (SELECT id FROM portalpage WHERE username IS NULL AND id != <default_dashboard_id>);
Last modified on Apr 19, 2024

Was this helpful?

Yes
No
Provide feedback about this article
Powered by Confluence and Scroll Viewport.