makeplane / makeplane/plane

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

Open
#9,592 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
59.6k
Forks
5.8k
Avg merge
1d 22h
Merged PRs (30d)
49

Description

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]:

https://github.com/makeplane/plane/blob/1c8a60f858d8472aa56e29994ec1c7926da2c6ce/apps/web/core/components/issues/issue-modal/base.tsx#L118-L120

// 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:

https://github.com/makeplane/plane/blob/1c8a60f858d8472aa56e29994ec1c7926da2c6ce/apps/web/core/components/issues/issue-modal/provider.tsx#L30

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).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with apps/web/core/components/issues/issue-modal/base.tsx and provider.tsx, then compare the project order from joinedProjectIds with the project-roles API response. Use the curl examples to reproduce both ordering cases. Done means the modal selects the first visible sidebar project and never selects an archived project.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, typescript
Domain
full-stack
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.