nexu-io/open-design · error · AutomationWorkspaceScopeError

WORKSPACE_ACCESS_DENIED

WORKSPACE_ACCESS_DENIED

Error message

the automation Workspace is no longer writable by this member

What it means

Thrown by authorizePersistedAutomationWorkspaceScope with code WORKSPACE_ACCESS_DENIED and retryable=false. After fetching the directory, the persisted (workspaceId, workspaceMemberId) pair either is not present in the directory or activeWritableContext() returned null (member is inactive or lacks write permission). This is a permanent authorization state until an admin changes roles.

Source

Thrown at apps/daemon/src/automations/workspace-scope.ts:135

}

/**
 * Re-authorize a Workspace/member pair captured when an unattended automation
 * was configured. No daemon-global current/active Workspace participates.
 */
export async function authorizePersistedAutomationWorkspaceScope(
  scope: PersistedAutomationWorkspaceScope,
  fetchWorkspaceDirectory: (() => Promise<WorkspaceDirectoryFetchResult>) | undefined,
): Promise<WorkspaceCollabContext> {
  const items = await fetchDirectoryOrThrow(fetchWorkspaceDirectory);
  const item = items.find(
    (candidate) =>
      candidate.workspaceId === scope.workspaceId
      && candidate.workspaceMemberId === scope.workspaceMemberId,
  );
  const context = activeWritableContext(item ? workspaceContextFromDirectoryItem(item) : null);
  if (!context) {
    throw new AutomationWorkspaceScopeError(
      'WORKSPACE_ACCESS_DENIED',
      'the automation Workspace is no longer writable by this member',
      false,
    );
  }
  return context;
}

/**
 * Resolve a reused project's persisted binding. The project row chooses the
 * Workspace; the signed-in directory supplies the current member and authority.
 */
export async function authorizePersistedProjectWorkspace(
  workspaceIdInput: string,
  fetchWorkspaceDirectory: (() => Promise<WorkspaceDirectoryFetchResult>) | undefined,
): Promise<WorkspaceCollabContext> {
  const workspaceId = workspaceIdInput.trim();
  const items = await fetchDirectoryOrThrow(fetchWorkspaceDirectory);

View on GitHub (pinned to 5be4028344)

Solutions

  1. Have a workspace admin restore the member's write role or re-add them to the workspace.
  2. Reassign the automation to a current active member with write access.
  3. If the automation is obsolete, delete it rather than retrying (retryable=false).
Defensive patterns

Strategy: try-catch

Validate before calling

// Before persisting, confirm the member is currently writable.
async function memberStillWritable(fetcher: () => Promise<{ ok: boolean; items: Array<{ workspaceId: string; workspaceMemberId: string; writable: boolean }> }>, scope: { workspaceId: string; workspaceMemberId: string }): Promise<boolean> {
  const dir = await fetcher();
  if (!dir.ok) return false;
  const item = dir.items.find(i => i.workspaceId === scope.workspaceId && i.workspaceMemberId === scope.workspaceMemberId);
  return Boolean(item && item.writable);
}

Try / catch

try {
  await authorizePersistedAutomationWorkspaceScope(scope, fetcher);
} catch (err) {
  if (err instanceof AutomationWorkspaceScopeError && err.code === 'WORKSPACE_ACCESS_DENIED') {
    // retryable === false: do NOT retry. Surface to the user for admin action.
    return forbidden('You no longer have write access to this Workspace. Contact a workspace admin.');
  }
  throw err;
}

Prevention

When it happens

Trigger: The member was removed from the workspace, had their role downgraded below write, or the workspace was deactivated; a stale automation whose member id no longer maps to an active account.

Common situations: Org reshuffles; an automation created by a user who later left the team; sandbox/preview workspace that was archived.

Related errors


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/24a520541e9bd233. Report an issue: GitHub.