Skip to content

Workspace creation isn't atomic and can lock the owner out #340

Description

@cavidelizade

Summary

Creating a workspace isn't atomic and the "add owner as member" error is discarded. If that second write fails, the workspace exists with no members and the owner is locked out of it.

Where

apps/web... backend: WorkspaceService.Create (apps/api/internal/service/workspace.go):

s.ws.Create(w)
_ = s.ws.AddMember(m)   // separate statement, error ignored, no transaction

Since IsMember gates all access, a failed AddMember leaves a workspace the creator can't see or clean up through the UI. ProjectStore.CreateWithCreatorMember already does the equivalent in a single transaction, so there's a pattern to follow.

There's a related shape in handler/auth.go (createDefaultWorkspace, at least logged) and the invite auto-accept path uses a plain Create for AddMember that can also hit a soft-deleted membership row.

Fix

Wrap the workspace insert and the owner membership insert in one transaction (mirror CreateWithCreatorMember).

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