Skip to content

Deleting a workspace fails with toast "Failed to delete artist link" #1808

Description

@sweetmantech

Summary: Clicking "Delete" in a workspace's settings shows an error toast "Failed to delete artist link" (bottom-right) and the workspace is not deleted. Artist deletion works fine.

Steps to reproduce

  1. Open settings for a workspace (repro account: 1e6c40e0-fdc6-4b69-856e-17d7b86d44a3).
  2. Click the Delete button.
  3. Toast appears (bottom-right): "Failed to delete artist link".

Expected vs actual

  • Expected: the workspace is deleted (no error).
  • Actual: error toast; the workspace remains.

Root cause

The workspace Delete reuses the artist delete flow, but a workspace's owner link lives in a different table.

  • chat: components/ArtistSetting/DeleteModal.tsx:12-20hooks/useDeleteArtist.ts:32lib/artists/deleteArtist.ts:14-26 issues DELETE {API}/api/artists/{id}. On failure it throws new Error(data.error || …) (deleteArtist.ts:25), so the toast text is the api's error string (which is why "Failed to delete artist link" doesn't appear anywhere in the chat repo).
  • api: app/api/artists/[id]/route.tslib/artists/deleteArtistHandler.tslib/artists/deleteArtist.ts:26-29:
    const deletedLinks = await deleteAccountArtistId(requesterAccountId, artistId);
    if (!deletedLinks.length) {
      throw new Error("Failed to delete artist link");
    }
    deleteAccountArtistId deletes from account_artist_ids (lib/supabase/account_artist_ids/deleteAccountArtistId.ts:18-30). Workspaces store their owner link in a different table, account_workspace_ids (written at creation — lib/workspaces/createWorkspaceInDb.ts:40), so the delete matches 0 rows and throws. The access guard passes earlier via the org-share path (lib/artists/checkAccountArtistAccess.ts:36-49), so it isn't blocked before reaching the failing delete.

Data model: both artists and workspaces are accounts rows; the distinguishing relationship is which join table holds membership — account_artist_ids (artist) vs account_workspace_ids (workspace). The delete endpoint hard-codes the artist table.

Proposed fix

Preferred — workspace-aware delete: add DELETE /api/workspaces/{id} that deletes from account_workspace_ids (new deleteAccountWorkspaceId(requester, workspaceId) under lib/supabase/account_workspace_ids/), plus cleanup of the accounts / account_info / artist_organization_ids rows on last-owner removal; then branch the chat delete on isWorkspace (the create flow already tags workspaces — CreateWorkspaceModal.tsx:59-62) to call a deleteWorkspace client fn.

Smaller-blast alternative: make api/lib/artists/deleteArtist.ts fall back to deleting the account_workspace_ids row before throwing; only error if neither table matched. Cleaner long-term is the dedicated endpoint (codebase keeps account/artist/workspace distinct).

Done when

  • Deleting a workspace removes it with no error toast.
  • Deleting an artist still works.

Suspected code

  • chat: components/ArtistSetting/DeleteModal.tsx:12-20, hooks/useDeleteArtist.ts:32,36, lib/artists/deleteArtist.ts:14-26
  • api: app/api/artists/[id]/route.ts, lib/artists/deleteArtist.ts:26-29 (throws here), lib/supabase/account_artist_ids/deleteAccountArtistId.ts:18-30, lib/artists/checkAccountArtistAccess.ts:36-49, lib/workspaces/createWorkspaceInDb.ts:40, lib/supabase/account_workspace_ids/

Filed in chat per house rule even though most of the fix lands in api — links out by full ref.

Found while testing chat#1793 (artist Connectors tab).

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    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