windmill-labs/windmill · error · Error

You can only delete forked workspaces where the workspace id

Error message

You can only delete forked workspaces where the workspace id starts with \`${WM_FORK_PREFIX}. Failed while attempting to delete \`${workspace.workspaceId}\`

What it means

`wmill workspace fork delete` only deletes forked workspaces. `deleteWorkspaceFork` looks up the workspace profile by name and verifies its workspace id starts with the fork prefix (`wm-fork`); otherwise it throws rather than deleting a non-fork workspace by mistake.

Source

Thrown at cli/src/commands/workspace/fork.ts:557

async function deleteWorkspaceFork(
  opts: GlobalOptions & {
    yes?: boolean;
  },
  name: string,
) {
  let forkWorkspaceId: string;
  let token: string;
  let remote: string;
  let hasLocalProfile = false;

  // Try local profile first (existing behavior)
  const orgWorkspaces = await allWorkspaces(opts.configDir);
  const idxOf = orgWorkspaces.findIndex((x) => x.name === name);

  if (idxOf !== -1) {
    const workspace = orgWorkspaces[idxOf];
    if (!workspace.workspaceId.startsWith(WM_FORK_PREFIX)) {
      throw new Error(
        `You can only delete forked workspaces where the workspace id starts with \`${WM_FORK_PREFIX}.\` Failed while attempting to delete \`${workspace.workspaceId}\``,
      );
    }
    forkWorkspaceId = workspace.workspaceId;
    token = workspace.token;
    remote = workspace.remote;
    hasLocalProfile = true;
  } else {
    // Fallback: resolve parent workspace from branch config and construct fork ID
    const parentWorkspace = await tryResolveBranchWorkspace(opts);
    if (!parentWorkspace) {
      throw new Error(
        "Could not resolve parent workspace. Make sure you are in a git repo with 'workspaces' configured in wmill.yaml, or create a local workspace profile for the fork.",
      );
    }
    forkWorkspaceId = name.startsWith(`${WM_FORK_PREFIX}-`) ? name : `${WM_FORK_PREFIX}-${name}`;
    token = parentWorkspace.token;
    remote = parentWorkspace.remote;

View on GitHub (pinned to e474e8803c)

Solutions

  1. Pass the fork's name/id (a workspace whose id starts with `wm-fork`)
  2. Run `wmill workspace list` to confirm the correct fork workspace name
  3. If you really want to remove a non-fork workspace, use the regular workspace remove command, not fork delete

Example fix

// before
wmill workspace fork delete prod   # id: prod
// after
wmill workspace fork delete my-feature   # id: wm-fork-my-feature
Defensive patterns

Strategy: type-guard

Validate before calling

const ws = (await allWorkspaces(opts.configDir)).find(w => w.name === name);
if (ws && !ws.workspaceId.startsWith('wm-fork')) {
  throw new Error(`${ws.workspaceId} is not a fork`);
}

Type guard

function isForkWorkspace(w: { workspaceId: string }): boolean {
  return w.workspaceId.startsWith(WM_FORK_PREFIX);
}

Try / catch

try {
  await deleteWorkspaceFork(name, opts);
} catch (e) {
  if (e.message.includes('only delete forked workspaces')) {
    log.error('Target is not a fork; use regular workspace removal.');
  } else throw e;
}

Prevention

When it happens

Trigger: Running `wmill workspace fork delete <name>` where the resolved workspace's id does not start with `wm-fork` (e.g. it is the production/parent workspace).

Common situations: Passing the parent workspace name instead of the fork name; a fork that was created without the prefix (manually renamed id); typo in the fork name resolving to a normal workspace.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/81b3038258d69c2f. Report an issue: GitHub.