Budibase/budibase · error · HTTPError

Destination workspace does not exist

Error message

Destination workspace does not exist

What it means

Thrown by getDestinationDb during resource copy/import operations when the target workspace's dev database does not exist (checked with skip_setup so it is never auto-created). The copy operation is refused with a 400 rather than silently creating an empty destination.

Source

Thrown at packages/server/src/sdk/workspace/resources/index.ts:362

      ]

      addDependencies(project._id, directMembers)
      // e.g. a project-assigned query may depend on a table, which depends on a datasource.
      for (const member of directMembers) {
        addDependencies(project._id, collectTransitiveDependencies(member.id))
      }
    }
  }

  return dependencies
}

async function getDestinationDb(toWorkspace: string) {
  const destinationDb = db.getDB(db.getDevWorkspaceID(toWorkspace), {
    skip_setup: true,
  })
  if (!(await destinationDb.exists())) {
    throw new HTTPError("Destination workspace does not exist", 400)
  }

  return destinationDb
}

const resourceTypeIdPrefixes: Record<ResourceType, string> = {
  [ResourceType.PROJECT]: prefixed(DocumentType.PROJECT),
  [ResourceType.AGENT]: prefixed(DocumentType.AGENT),
  [ResourceType.DATASOURCE]: prefixed(DocumentType.DATASOURCE),
  [ResourceType.TABLE]: prefixed(DocumentType.TABLE),
  [ResourceType.ROW_ACTION]: prefixed(DocumentType.ROW_ACTIONS),
  [ResourceType.QUERY]: prefixed(DocumentType.QUERY),
  [ResourceType.AUTOMATION]: prefixed(DocumentType.AUTOMATION),
  [ResourceType.WORKSPACE_APP]: prefixed(DocumentType.WORKSPACE_APP),
  [ResourceType.SCREEN]: prefixed(DocumentType.SCREEN),
}

function getResourceType(id: string): ResourceType | undefined {

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Confirm the destination workspace/app exists (list apps or open it in the builder) before running the copy
  2. Create the destination workspace/app first, then retry the copy
  3. Verify toWorkspace is the app/workspace id of the same tenant, not a name or an id from another environment
  4. Check the destination's dev DB directly in CouchDB to confirm it wasn't deleted

Example fix

// before
await resources.copy(table, { toWorkspace: targetAppId })
// after
const target = await workspaces.get(targetAppId)
if (!target) throw new Error(`Destination app ${targetAppId} missing`)
await resources.copy(table, { toWorkspace: targetAppId })
Defensive patterns

Strategy: validation

Validate before calling

const dest = await workspaces.get(toWorkspace)
if (!dest) throw new Error(`Destination workspace ${toWorkspace} not provisioned`)

Type guard

function isWorkspaceId(id: string): boolean
  return typeof id === "string" && id.length > 0 && id !== "undefined" && id !== "null"

Try / catch

try {
  await copyResources(payload, toWorkspace)
} catch (e) {
  if (e?.status === 400 && /Destination workspace/i.test(e.message)) {
    throw new Error(`Create workspace ${toWorkspace} before copying`)
  }
  throw e
}

Prevention

When it happens

Trigger: Calling a resource copy/import (e.g. duplicating a table or datasource into another workspace) where `toWorkspace` refers to an app id that has never been created or whose dev database was deleted; passing a workspace/app id from a different tenant.

Common situations: Copying resources into an app id from an environment export that was never provisioned; typo'd or stale app id in automation/script; the destination app was deleted while a copy job was queued; cross-tenant id reuse.

Related errors


AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29). Data as JSON: /api/errors/95839daa3bc264e1. Report an issue: GitHub.