Anti-patterns are approaches that fewer than 2 of 10 systems use—often for good reason. Permission anti-patterns are especially costly because they affect trust: a confusing removal dialog or a dead-end 403 page doesn't just frustrate users, it makes them question whether your system is safe to rely on.
Category
Anti-Patterns
Access Denied
3 anti-patterns
Request Access
2 anti-patterns
Destructive Actions
3 anti-patterns
Role & Microcopy
3 anti-patterns
Access Denied Anti-Patterns
Anti-Pattern 1: Technical Language on Denied Pages
Frequency: 1 of 7 systems (Linear)
Using developer-facing language like "Authentication error" as the headline when a user hits a permission wall.
Linear's 'Authentication error' — technically accurate, but the user doesn't know what authentication means or how to fix it
Why it fails:
Users don't think in HTTP status codes or auth protocols
"Authentication error" sounds like something is broken, not that they lack permission
Creates anxiety instead of clarity
Better alternative: "No access to this page" (Notion), "It looks like you don't have access to this" (Asana). Direct language that explains the situation without technical framing.
Anti-Pattern 2: Dead-End Denied Pages
Frequency: 3 of 7 systems (GitHub, Linear, Asana)
Showing an access-denied page with no actionable recovery path — no "Request access" button, no "Switch account" option, just a message and nowhere to go.
Airtable's dead-end invite failure — no explanation of why, no CTA to request a new invite, no next step
Why it fails:
User has no way to resolve the problem themselves
Generates support tickets that could be avoided
Feels like a closed door with no doorbell
Better alternative: Always include at least one recovery path. Notion's pattern is the strongest: "Request access" as primary CTA, "Back to my content" as secondary, plus account context at the bottom.
Anti-Pattern 3: Hiding Resource Existence (Without Security Need)
Frequency: 1 of 7 systems (GitHub)
Showing a 404 page instead of a 403 — pretending the resource doesn't exist when the user simply lacks access.
GitHub shows 404 for private repos — a deliberate security choice, but one that leaves users with zero recovery
When it's justified: GitHub does this deliberately for private repositories — revealing that a repo exists but you can't access it leaks information. For code hosting, this is a valid security pattern.
When it's an anti-pattern: For collaboration tools (documents, projects, boards), hiding existence creates confusion. The user knows the resource exists — someone sent them the link. Showing 404 instead of 403 feels like gaslighting.
Better alternative: For non-security contexts, show a clear denied page with "Request access" — the person knows the resource exists, so help them get in.
Request Access Anti-Patterns
Anti-Pattern 4: No Request-Access Flow
Frequency: 5 of 10 systems lack this entirely (GitHub, Slack, Linear, Airtable, Asana)
Half the systems offer no way for a blocked user to request access. If you don't have permission, your only option is to contact someone outside the product.
Why it fails:
Forces communication through side channels (Slack DMs, email, walking over to someone's desk)
Admin has no structured way to review and approve requests
Blocked user doesn't know who to ask
Creates friction that discourages collaboration
Better alternative: Figma, Notion, Dropbox, Trello, and Atlassian all offer request-access flows. The minimum viable version: a "Request access" button on the denied page that notifies the resource owner.
Anti-Pattern 5: Request Access Without Account Context
Frequency: 1 of 5 systems with request flows (Notion shows account but no switch option)
Showing a request-access page without telling the user which account they're signed in as, or without offering account switching.
Why it fails:
"I can't access this" is often "I'm signed into the wrong account"
User submits a request that wasn't needed — they just needed to switch accounts
Creates unnecessary approval work for admins
Better alternative: 4 of 5 systems with request-access flows show the logged-in account and offer "Switch account" (Figma, Atlassian, Dropbox, Trello). Diagnose before escalating.
Destructive Action Anti-Patterns
Anti-Pattern 6: Vague Destructive CTAs
Frequency: 1 of 9 systems each
Three systems avoid the consensus "Remove" verb for destructive actions:
System
CTA
Problem
Notion
"Continue"
Doesn't describe the action — could mean anything
Slack
"Deactivate"
Softer framing, but inconsistent with industry
Linear
"Confirm"
Generic — confirm what?
Why it fails:
"Continue" is the worst offender — it's the CTA for proceeding through a multi-step flow, not for removing someone
Users may click without fully registering what they're agreeing to
Adds cognitive load: "What exactly am I confirming?"
Better alternative: "Remove" — 6 of 9 systems agree. It's unambiguous, direct, and sets clear expectations. Put the person's name in the headline or button for extra clarity: "Remove haalandjan from this repository" (GitHub).
Anti-Pattern 7: Removal Without Consequence Disclosure
Frequency: 2 of 9 systems (Figma, Linear)
Showing a removal confirmation with no explanation of what the person loses.
Why it fails:
Admin doesn't know the blast radius of their action
May accidentally remove someone from more than intended
No way to assess risk before confirming
Leads to "I didn't realize that would happen" moments
Better alternative: Explicit consequences. Trello does this best: "Jan Haaland will be removed from all cards on this board." Slack explains: "This member will be deactivated and lose access to this workspace." Even a general statement ("All access will be lost immediately" — Atlassian) is better than silence.
Anti-Pattern 8: Feedback Survey During Destructive Actions
Frequency: 1 of 9 systems (Notion)
Collecting product feedback ("Why are you removing this member?") as part of the removal flow, with the destructive action gated behind the survey.
Why it fails:
Conflates product analytics with a critical security action
Adds friction to an already high-stakes flow
User may feel their reason is being judged
"Continue" CTA (not "Remove") further obscures what's happening
Better alternative: Collect feedback after the action, not as a gate. The removal flow should be: confirm identity → show consequences → "Remove." Analytics can come later.
Unlock 6 more sections
Subscribe to access the full content and unlock all chapters.
Locked sections:
When showing 404 instead of 403 is justified — and when it's gaslighting your users
Why half the industry has no request-access flow — and how to build one that works
The 3 destructive CTA verbs that confuse users — and why 'Remove' is the only safe choice
Why 2 systems skip consequence disclosure during removal — and the exact patterns that prevent 'I didn't realize that would happen'
The role description mistake that causes over-permissioning — and the inline pattern 7 of 9 systems use instead
Complete summary table of all 11 anti-patterns with frequencies and alternatives