langgenius/dify · error · BaseError

AccessDenied

AccessDenied

Error message

no workspaces available to switch to

What it means

Thrown after the workspace list is fetched successfully but contains zero entries. The code uses AccessDenied (exit code 4, the Auth bucket) because the account effectively has no workspace it can switch to. It is a server-state condition, not a parser error: client.list() returned an empty workspaces array. Note this fires only on the no-id interactive path; with an explicit id the code skips the list and goes straight to client.switch(id), which would surface a different error if the id is invalid.

Source

Thrown at cli/src/commands/use/workspace/use.ts:72

  deps.io.out.write(`${cs.successIcon()} Switched to ${detail.name} (${detail.id})\n`)
  return deps.reg
}

async function pickWorkspaceId(client: WorkspacesClient, deps: UseWorkspaceDeps): Promise<string> {
  if (!deps.io.isErrTTY) {
    throw new BaseError({
      code: ErrorCode.UsageMissingArg,
      message: 'a workspace id is required (no TTY)',
      hint: "pass the id: 'difyctl use workspace <id>'",
    })
  }

  const list = await runWithSpinner({ io: deps.io, label: 'Loading workspaces' }, () =>
    client.list(),
  )
  const items = list.workspaces.map<Workspace>((w) => ({ id: w.id, name: w.name, role: w.role }))
  if (items.length === 0) {
    throw new BaseError({
      code: ErrorCode.AccessDenied,
      message: 'no workspaces available to switch to',
    })
  }

  const activeId = deps.active.ctx.workspace?.id
  const picked = await selectFromList<Workspace>({
    io: deps.io,
    items,
    header: 'Select a workspace',
    render: (w) => `${w.id === activeId ? '* ' : '  '}${w.name} (${w.role})`,
  })
  return picked.id
}

View on GitHub (pinned to ef8544b173)

Solutions

  1. Have an admin invite the account to a workspace, or accept a pending invitation via the Dify UI/API.
  2. Create a workspace if the account is allowed to (`difyctl workspaces create <name>` if supported), then re-run `difyctl use workspace`.
  3. Confirm the account you logged in with is the one you expect: `difyctl whoami` — a wrong or service account often has no workspaces.
  4. Check the instance endpoint with `difyctl workspaces list -o json` to confirm the empty list isn't a transient API issue; if list itself errors, investigate auth/network first.
Defensive patterns

Strategy: validation

Validate before calling

// pre-fetch the workspace list and short-circuit on empty with a domain-specific message
const list = await client.list()
if (list.workspaces.length === 0) {
  // surface a friendlier message than the raw 'no workspaces available'
  throw new BaseError({ code: ErrorCode.AccessDenied, message: 'account has no workspaces; ask an admin to invite you' })
}
const items = list.workspaces.map((w) => ({ id: w.id, name: w.name, role: w.role }))

Prevention

When it happens

Trigger: Account exists but belongs to no workspaces (new signup before workspace provisioning, removed from all workspaces, or an instance where the user is only a member of the default workspace that was deleted). Reached when `client.list()` resolves with `list.workspaces` of length 0 at use.ts:70-71. The picker is then unreachable because there is nothing to render.

Common situations: Freshly created account on a self-hosted Dify instance where workspace provisioning is pending or failed; user was removed from their last workspace; SSO-provisioned account whose workspace mapping hasn't synced; test/staging account that never joined a workspace; a personal workspace that an admin deleted.

Related errors


AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12). Data as JSON: /api/errors/57c141fc53f49506. Report an issue: GitHub.