What protect() actually does (and doesn't do)
Calling range.protect() creates a Protection object and registers it with the spreadsheet. That part works fine. What catches people is that the newly created protection inherits the spreadsheet's existing editor list — so every collaborator who already had edit access to the file still has edit access to the protected range. The range is technically protected, but the list of permitted editors is still wide open.
The fix is to call protection.getEditors() immediately after creating the protection, then pass that array directly to protection.removeEditors(). That call wipes the inherited list. You then add back only the accounts you actually want to allow. In most automation scenarios, that's just the owner: SpreadsheetApp.getActiveSpreadsheet().getOwner().
The first time I hit this, I spent twenty minutes in the Sheets UI confirming the protection was listed but couldn't figure out why a shared account was still overwriting cells. The protection was real; the editor list was the problem.