Skip to content

[bug]: "New work item" preselects a project that does not match the sidebar order, and can preselect an archived project #9592

Description

@gaerae

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

When a workspace has several projects, the project that the New work item modal preselects has nothing to do with the order the projects are listed in — not in the sidebar, and not in the modal's own project dropdown.

The modal falls back to allowedProjectIds[0]:

// if data is not present, set active project to the first project in the allowedProjectIds array
if (allowedProjectIds && allowedProjectIds.length > 0 && !activeProjectId)
setActiveProjectId(projectId?.toString() ?? allowedProjectIds?.[0]);

// if data is not present, set active project to the first project in the allowedProjectIds array
if (allowedProjectIds && allowedProjectIds.length > 0 && !activeProjectId)
  setActiveProjectId(projectId?.toString() ?? allowedProjectIds?.[0]);

and allowedProjectIds is built in the issue modal provider from the key order of the permission map:

const projectIdsWithCreatePermissions = Object.keys(projectsWithCreatePermissions ?? {});

const projectIdsWithCreatePermissions = Object.keys(projectsWithCreatePermissions ?? {});

projectsWithCreatePermissions comes from GET /api/users/me/workspaces/<slug>/project-roles/, which returns a plain {project_id: role} object built from a ProjectMember queryset. With no explicit order_by, it uses the model default ("-created_at",), so the keys are ordered by when the user joined each project, newest first.

Everything the user actually sees is ordered by sort_order instead (joinedProjectIds in the project store, used by the sidebar and by ProjectDropdown). The two orders coincide on a fresh workspace, but they drift apart as soon as projects are reordered by drag and drop, because dragging changes ProjectUserProperty.sort_order and never touches ProjectMember.created_at.

Two consequences:

  1. Wrong default project. With the sidebar ordered Alpha, Bravo, Echo, Delta, Charlie, Foxtrot, the modal preselects Foxtrot — the last project in the list. Work items silently land in the wrong project when the title is typed and saved without checking the project chip.

  2. Archived projects can be preselected, and saving then fails with a 500. The project-roles response is not filtered by archived_at, so an archived project can be allowedProjectIds[0]. It is not in the project dropdown (that list comes from joinedProjectIds, which excludes archived projects), so the modal preselects a project the user cannot even see or pick, and Save fails:

POST /api/workspaces/<slug>/projects/<archived project id>/issues/ → 500

TypeError: 'NoneType' object is not iterable
  File "/code/plane/app/views/issue/base.py", line 458, in create
    issue = user_timezone_converter(issue, datetime_fields, request.user.user_timezone)
  File "/code/plane/utils/timezone_converter.py", line 25, in user_timezone_converter
    queryset_values = list(queryset)

Expected: the modal preselects the first project of the list the user sees, and never preselects an archived project.

Steps to reproduce

  1. Create a workspace and six projects, AlphaFoxtrot, in that order. The sidebar lists them newest first: Foxtrot, Echo, Delta, Charlie, Bravo, Alpha.
  2. Drag Alpha and Bravo to the top and Foxtrot to the bottom, so the sidebar reads Alpha, Bravo, Echo, Delta, Charlie, Foxtrot.
  3. Go to Home and click New work item.
  4. The project chip shows Foxtrot, the last project in the sidebar, instead of Alpha.

For the archived-project variant, archive Foxtrot after step 2 and reload. It disappears from the sidebar and from the modal's project dropdown, but the modal still preselects it, and saving returns a 500.

Both orders can be read straight from the API:

# sidebar order (sort_order asc)
curl -s -b "session-id=$SESSION" $HOST/api/workspaces/$SLUG/projects/ \
  | jq -r 'sort_by(.sort_order) | map(.name) | join(", ")'
# => Alpha, Bravo, Echo, Delta, Charlie, Foxtrot

# order the modal picks its default from
curl -s -b "session-id=$SESSION" $HOST/api/users/me/workspaces/$SLUG/project-roles/ | jq -r 'keys_unsorted'
# => Foxtrot, Echo, Delta, Charlie, Bravo, Alpha  (resolved to names)

Environment

Self-hosted

Browser

Google Chrome

Variant

Self-hosted

Version

v1.3.1, also reproduced on v1.4.1 and on preview (the code is unchanged across all three).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions