stablyai/orca · error · AggregateError

Cookie replacement and rollback failed

Error message

Cookie replacement and rollback failed

What it means

Thrown as an AggregateError by replaceCookiesForImportedDomains when a store.remove() call fails AND the subsequent rollback (restoreImportedDomainCookies to re-add already-removed cookies) also fails. This is the worst-case double-failure: the replacement couldn't remove a cookie, and the attempt to undo prior successful removals also failed — leaving the cookie jar in a partially-modified state. The AggregateError contains both the removal error and the restore error.

Source

Thrown at src/main/browser/browser-cookie-import-policy.ts:275

  const existingCookies = await store.get({})
  const removedCookies: Cookie[] = []
  for (const cookie of existingCookies) {
    const domain = cookie.domain ? normalizeCookieDomain(cookie.domain) : null
    if (!domain || !overlapsImportedDomain(cookie, domain, scopes)) {
      continue
    }
    const url = cookieRemovalUrl(cookie, domain)
    if (!url) {
      continue
    }
    try {
      await store.remove(url, cookie.name)
      removedCookies.push(cookie)
    } catch (err) {
      try {
        await restoreImportedDomainCookies(store, removedCookies)
      } catch (restoreError) {
        throw new AggregateError([err, restoreError], 'Cookie replacement and rollback failed')
      }
      throw err
    }
  }
  return removedCookies
}

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Inspect both errors in the AggregateError: the first is the removal failure, the second is the restore failure — address the root cause of the removal failure first.
  2. After this error, re-fetch all cookies (store.get({})) and reconcile against the expected state — the jar is partially modified.
  3. Avoid running cookie replacement during session teardown or while the page is actively setting cookies (race).
  4. Retry the full replaceCookiesForImportedDomains operation after the store stabilizes — it is idempotent (removes overlapping cookies, skipped ones are no-ops).
Defensive patterns

Strategy: try-catch

Type guard

function isAggregateError(e: unknown): e is AggregateError {
  return e instanceof AggregateError && Array.isArray(e.errors)
}

Try / catch

try {
  await replaceCookiesForImportedDomains(store, importedDomains)
} catch (e) {
  if (e instanceof AggregateError && /replacement and rollback/i.test(e.message)) {
    // jar is partially modified — reconcile by re-fetching and comparing
    const current = await store.get({})
    // re-attempt the idempotent replacement now that store may have stabilized
    await replaceCookiesForImportedDomains(store, importedDomains)
  }
  throw e
}

Prevention

When it happens

Trigger: replaceCookiesForImportedDomains iterates existing cookies overlapping imported domains; for each, store.remove(url, name) is called. If remove fails for one cookie after others were already removed, it calls restoreImportedDomainCookies to put back the removed ones. If THAT restore also throws (see error 797), both errors are aggregated into 'Cookie replacement and rollback failed'. The cookie jar is now in an inconsistent state — some imported-domain cookies removed, rollback incomplete.

Common situations: Electron's cookie store is in a degraded state (session being torn down, partition unmounted); a cookie removal fails due to a URL/domain mismatch while the rollback cookies have malformed attributes that fail re-set; concurrent cookie mutations from the page racing with the replacement; Electron version bug in remove()/set() atomicity.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/ff2e585232c60ebd. Report an issue: GitHub.