100 Ways to Break a Canvas App on Purpose (So You Learn Faster) - Part 2

  • avatar
    Admin Content
  • Jul 23, 2025

  • 14

Collections, Navigation Nightmares, UX Mayhem & Security Slip-ups 

Intro: If you’re reading this, congratulations: you’ve survived 50 intentional disasters and now possess stronger Patch() instincts, cleaner variable usage, and probably a bit of emotional scarring. Now, let’s finish the job. Part 2 dives into everything from Collection chaos and Navigation drama to UX disasters , Security nightmares , and the sweet self-sabotage of app dev culture. 


🧺 Section 6: Collection Carnage – Where Temp Data Goes to Die 

 

  1. Collecting From Multiple Screens Without Sync Breaks when: You use the same collection from different screens assuming it auto-syncs. Fix it like a boss: Use ClearCollect() at App start or when switching screens. 
  2. No ClearCollect() Before Re-collecting Breaks when: You collect repeatedly without clearing — enjoy your duplicates. Fix it: Always use ClearCollect() instead of Collect() for refreshable data. 
  3. Assuming Collections Persist After Close Breaks when: You expect a collection to still be there after the app reloads. Fix it: Use SaveData() and LoadData() for offline persistence. 
  4. Collecting Nested Tables Into a Flat List Breaks when: You try to Collect() a field with nested records. Fix it: Use ForAll() and AddColumns() to flatten nested data before collecting. 
  5. Column Name Collisions Breaks when: Multiple data sources share column names and overwrite in a Collect(). Fix it: Rename columns explicitly using RenameColumns() before merging. 
  6. Overcollecting Instead of Direct Binding Breaks when: You collect the entire data source when binding directly would suffice. Fix it: Bind controls to direct data where possible, especially for small sets. 
  7. Missing Fields in Collection Records Breaks when: You Collect() only partial fields and later Patch() them. Fix it: Ensure full schema consistency using ShowColumns() or mapped schema. 
  8. One-Row-at-a-Time ForAll() + Collect() Breaks when: You loop through 1000 records to collect them individually. Fix it: Use bulk ClearCollect() or server-side logic instead. 
  9. Not De-duplicating Before Display Breaks when: You show users a gallery with repeated rows. Fix it: Wrap collections in Distinct() or build deduplication into Collect() logic. 
  10. Forgetting to RemoveIf() Old Staged Data Breaks when: You don’t clean up staging collections before saves. Fix it: RemoveIf() records with an identifier or flag before saving. 

 


🧭 Section 7: Navigation Nightmares – Getting Lost in Your Own App 

 

  1. Navigating to Non-Existent Screens Breaks when: You delete a screen and forget it’s still referenced. Fix it like a boss: Use App Checker to clean up orphaned references. 
  2. Context Variables That Don’t Travel Breaks when: You set context on one screen and expect it to be available globally. Fix it: Pass data via Navigate(Screen, {}, {contextVar: value}). 
  3. Stale Form Data Across Screens Breaks when: You don’t reset forms when moving screens. Fix it: Use ResetForm() in the OnVisible or OnSelect logic. 
  4. Using Back() Instead of Navigate() Breaks when: You assume Back() returns to a specific screen — it doesn’t. Fix it: Use Navigate() for precision and Back() only when flow is linear. 
  5. OnVisible Triggers with Redirect Logic Breaks when: You navigate to a screen, and it instantly redirects somewhere else. Fix it: Add flags to control when navigation triggers. 
  6. ConfirmExit Confusion Breaks when: You enable ConfirmExit but don’t account for form state. Fix it: Use Unsaved flags with meaningful messages. 
  7. Looped Navigation Calls Breaks when: You conditionally navigate inside a loop or triggered update. Fix it: Add debounce logic or user-initiated triggers for navigation. 
  8. Missing Context on Deep Links Breaks when: A deep link opens your app but misses required screen context. Fix it: Use Param() with defensive fallbacks. 
  9. Confusing Launch() vs. Navigate() Breaks when: You think Launch() goes to another screen — it launches URLs! Fix it: Reserve Launch() for external links only. 
  10. Not Resetting Modal States Breaks when: You open modals via Visible and forget to reset their flags. Fix it: Always reset varShowModal or equivalent in OnHidden logic. 

 

😵 Section 8: UX Missteps – How to Confuse Users Instantly 

 

  1. Controls Bound Before Data Loads Breaks when: A dropdown tries to show colOptions before it’s populated. Fix it like a boss: Use loading indicators or disable controls until !IsEmpty(). 
  2. Perma-Spinners Breaks when: You set LoadingSpinner = true but forget to turn it off. Fix it: Use Concurrent() or Timer logic to control spinner visibility. 
  3. Control Names Like TextInput23 Breaks when: You have no idea what Dropdown5 is anymore. Fix it: Rename everything meaningfully. You’ll thank yourself later. 
  4. Unhandled Errors Explode on Screen Breaks when: Power Apps shows raw error messages. Fix it: Wrap calls in IfError() and use user-friendly messages. 
  5. No Submit Button Disabled State Breaks when: Users can submit a blank form 20 times. Fix it: Use DisplayMode = If(Form.Valid, DisplayMode.Edit, DisplayMode.Disabled). 
  6. Overstuffed Screens with 30+ Controls Breaks when: App performance tanks and layout goes bonkers. Fix it: Break UI into multiple screens or tabbed containers. 
  7. Accessibility? What Accessibility? Breaks when: Your app can’t be used with a keyboard or screen reader. Fix it: Set TabIndex and Labels for accessibility compliance. 
  8. Color-Coding Logic Backwards Breaks when: You show errors in green and success in red. Fix it: Follow standard color conventions — your users will panic less. 
  9. Popups Without Dismiss Logic Breaks when: Users get stuck in a modal and can’t get out. Fix it: Provide close buttons or Esc key logic. 
  10. Text That Doesn’t Wrap or Scale Breaks when: Your tooltips or labels get cut off. Fix it: Use AutoHeight, wrap text settings, and responsive layouts. 

 


🔐 Section 9: Security Sinkholes – The Data Exposé 

 

  1. Everyone Gets Edit Access Breaks when: Every user can change every record. Fix it like a boss: Set SharePoint list permissions or use Dataverse roles. 
  2. Using Hidden Controls for Security Breaks when: You hide a button and call it “secure.” Fix it: Never rely on visibility to secure actions. Use server-side rules. 
  3. Local Collection Role Checks Breaks when: You store user roles in a collection that anyone can edit. Fix it: Fetch roles from a secure source at runtime. 
  4. Client-Side Filtering of Secure Data Breaks when: All data is downloaded, and the client filters out what they shouldn't see. Fix it: Apply row-level security at the source. 
  5. Assuming Power Apps = SharePoint Permissions Breaks when: Users can access lists you thought were hidden. Fix it: Configure both app logic and backend list permissions. 
  6. Hardcoding Email Checks Breaks when: You write If(User().Email = "bob@company.com", ...). Fix it: Use role lists or lookup tables, not hardcoded logic. 
  7. Environment Variables Left Wide Open Breaks when: All users can see or modify your environment values. Fix it: Restrict who can manage these via solution security roles. 
  8. Publishing to Everyone Breaks when: You hit “Share with Organization” without testing roles. Fix it: Test with dummy users before org-wide release. 
  9. Saving Secrets in Collections Breaks when: Passwords or API keys are in app variables. Fix it: Use Azure Key Vault or environment secrets via Power Automate. 
  10. Delegation Holes in Security Filters Breaks when: Your Filter(Data, User().Email = Author.Email) isn’t delegable. Fix it: Use server-side filters and indexed columns, or pass permissions via Flow. 

 


🧠 Section 10: Bonus Round – Meta-Mistakes and Developer Self-Sabotage 

 

  1. No Comments in Formulas Breaks when: You revisit a formula three months later and have no clue what it does. Fix it like a boss: Use /* comments */ in formulas, or separate logic blocks. 
  2. Skipping App.OnStart Logic Breaks when: Your app loads without initializing anything. Fix it: Set up collections, context, and lookups in App.OnStart. 
  3. Screens Named Screen1, Screen2 Breaks when: You lose track of your app's flow. Fix it: Use descriptive names like scrHome, scrAdmin, scrSettings. 
  4. Putting Everything on One Screen Breaks when: Performance dies and UX confuses users. Fix it: Split logic into screens or tabs. Don’t fear modular design. 
  5. Avoiding Components Out of Fear Breaks when: You repeat the same control 8 times instead of reusing a component. Fix it: Build and reuse custom components for maintainability. 
  6. No Versioning Strategy Breaks when: You push updates directly to prod without backup. Fix it: Save app versions and use separate dev/test/prod environments. 
  7. Duplicating Formulas Across Screens Breaks when: You fix a bug once, and forget 5 other places. Fix it: Centralize logic in variables, components, or functions. 
  8. Ignoring Errors Until It’s Too Late Breaks when: Users experience failures you didn’t test for. Fix it: Use Monitor, IfError(), and testing accounts. 
  9. Testing as Yourself Only Breaks when: You test only under your full-permission dev account. Fix it: Use test users with different roles to simulate real behavior. 
  10. Never Using Monitor Breaks when: You spend hours debugging without tools. Fix it: Open the Monitor pane and never look back. 

 

Source: 100 Ways to Break a Canvas App on Purpose (So You Learn Faster) - Part 2
 

Get New Internship Notification!

Subscribe & get all related jobs notification.