Starting around mid-June 2026, our Excel Office add-in began failing on WorksheetProtection.unprotect().
The call throws:
RichApi.Error: AccessDenied — "You cannot perform the requested operation."
code: "AccessDenied"
httpStatusCode: 403
errorLocation: "WorksheetProtection.unprotect"
We did not deploy any change. Office.js is loaded from Microsoft's CDN, so this started for many users simultaneously — pointing to an Excel/Office.js update, not our code. protect(), delete(), and cell value/format writes all still work; only unprotect() is rejected.
Minimal reproduction
This fails even on a brand-new, natively-created sheet (no insertWorksheetsFromBase64 involved):
await Excel.run(async (context) => {
const sheet = context.workbook.worksheets.add();
await context.sync();
sheet.protection.protect({}, "myPassword"); // ✅ succeeds
await context.sync();
});
await Excel.run(async (context) => {
const sheet = context.workbook.worksheets.getItem(/* the new sheet */);
sheet.protection.unprotect("myPassword"); // ❌ AccessDenied (403)
await context.sync();
});
The exact same password works when unprotecting manually via Review → Unprotect Sheet.
What I've already tried (all still fail)
- unprotect(password), unprotect(""), and unprotect() (no arg)
- Re-fetching the sheet by id/name inside a fresh Excel.run
- Parameterless await context.sync() (vs context.sync(sheet)) — no difference
- Code-applied protection (protecting then immediately unprotecting in the same session)
- Brand-new worksheets.add() sheet, and sheets inserted via insertWorksheetsFromBase64 — both rejected
- pauseProtection() before unprotect() — throws NotImplemented (501) on Desktop; it appears to be ExcelApiOnline (web-only)
Environment
- Excel for Mac, Version 16.59.313.0 (also reproduced on Windows Build 16.0.20026.x)
- Office.js: https://appsforoffice.microsoft.com/lib/1.1/hosted/excel-mac-16.00.js
- Add-in (task pane), not Office Scripts
Questions
1. Is this an intentional Office Desktop security/hardening change, or a regression?
2. Is there a supported way to programmatically remove worksheet protection from an add-in now, given pauseProtection() is not implemented on Desktop?
3. If unprotect() is no longer available to add-ins, is the recommended pattern now "protect once with specific cells unlocked, and never unprotect"?