[bug]: "New work item" preselects a project that does not match the sidebar order, and can preselect an archived project
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]:
// 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 ?? {});
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:
-
Wrong default project. With the sidebar ordered
Alpha, Bravo, Echo, Delta, Charlie, Foxtrot, the modal preselectsFoxtrot— 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. -
Archived projects can be preselected, and saving then fails with a 500. The
project-rolesresponse is not filtered byarchived_at, so an archived project can beallowedProjectIds[0]. It is not in the project dropdown (that list comes fromjoinedProjectIds, which excludes archived projects), so the modal preselects a project the user cannot even see or pick, andSavefails:
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
- Create a workspace and six projects,
Alpha…Foxtrot, in that order. The sidebar lists them newest first:Foxtrot, Echo, Delta, Charlie, Bravo, Alpha. - Drag
AlphaandBravoto the top andFoxtrotto the bottom, so the sidebar readsAlpha, Bravo, Echo, Delta, Charlie, Foxtrot. - Go to Home and click New work item.
- The project chip shows
Foxtrot, the last project in the sidebar, instead ofAlpha.
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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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