Budibase/budibase · critical

Replication failed - ${JSON.stringify(err)}

Error message

Replication failed - ${JSON.stringify(err)}

What it means

The CLI's replication helper copies database contents between a remote CouchDB and a local PouchDB (or vice versa) using PouchDB replication options (batch size, main_only style). If the underlying replication call rejects, the raw error is serialized to JSON and rethrown with this prefix so callers of exportBackup/importBackup see replication-specific context.

Source

Thrown at packages/cli/src/backups/utils.ts:90

    environment._set(key, config[key])
  }
  return config
}

export async function replication(
  from: PouchDB.Database,
  to: PouchDB.Database
) {
  const pouch = getPouch()
  try {
    await pouch.replicate(from, to, {
      batch_size: 1000,
      batches_limit: 5,
      // @ts-ignore
      style: "main_only",
    })
  } catch (err) {
    throw new Error(`Replication failed - ${JSON.stringify(err)}`)
  }
}

export function getPouches(config: Record<string, string>) {
  const Remote = getPouch(config["COUCH_DB_URL"])
  const Local = getPouch()
  return { Remote, Local }
}

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Read the JSON payload in the message for the real cause (status code, URL, etc.)
  2. Verify CouchDB is reachable: `curl <COUCH_DB_URL>/_up` with the configured credentials
  3. Check COUCH_DB_URL, COUCH_DB_USER, COUCH_DB_PASSWORD in the CLI config
  4. Ensure no other process holds the local PouchDB/SQLite files locked
  5. Retry the backup/import; for large DBs increase timeouts or reduce concurrent batches

Example fix

# before
COUCH_DB_URL=http://localhost:4005  # server down / wrong port
# after
docker compose up -d couchdb && curl -u admin:password http://localhost:4005/_up
Defensive patterns

Strategy: retry

Validate before calling

async function assertCouchReachable(url: string, auth?: string) {
  const res = await fetch(`${url}/_up`, { headers: auth ? { Authorization: `Basic ${auth}` } : {} })
  if (!res.ok) throw new Error(`CouchDB not reachable at ${url}: ${res.status}`)
}

Try / catch

try {
  await replication(localPouch, remotePouch)
} catch (err) {
  if ((err as Error).message.startsWith("Replication failed")) {
    const cause = JSON.parse((err as Error).message.replace("Replication failed - ", ""))
    console.error("Replication error detail:", cause) // inspect status/result before retrying
  }
  throw err
}

Prevention

When it happens

Trigger: Calling exportBackup/importBackup when the remote COUCH_DB_URL is wrong or unreachable, CouchDB credentials are missing/invalid, the target database doesn't exist and can't be created, the DB is locked by another process, or a network interruption aborts the sync mid-flight.

Common situations: Self-hosted CouchDB container down or on a different port; wrong admin username/password in config; replicating to a server version incompatible with the local PouchDB adapter; large databases hitting timeouts; two CLI processes racing on the same local pouch file.

Related errors


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