Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Crash Risk Audit

ASecurity

Detects force unwraps, force casts, force try, and other crash-prone Swift patterns that can cause unrecoverable crashes during App Store review, violating Guideline 2.1.

18 stars
0 votes
0 copies
1 views
Added 9/20/2026
ai-agentsswiftbashreactdatabaseperformance

Security Analysis

A100/100

Scanned 9/20/2026

Install to Claude Code

$npx -y skills add cruisediary/apple-app-review-skills --skill crash-risk-audit --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Crash Risk Audit?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Crash Risk Audit
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/cruisediary-crash-risk-audit/badge)](https://www.skillsdirectory.com/skills/cruisediary-crash-risk-audit)

More formats (shields.io, HTML) on the badges page.

Download with Pro
Files
SKILL.md
---
name: crash-risk-audit
description: >-
  Detects force unwraps, force casts, force try, and other crash-prone Swift patterns that can cause unrecoverable crashes during App Store review, violating Guideline 2.1.
---

# Skill: Crash Risk Audit
<!-- SEO: force unwrap crash force cast try! fatalError EXC_BAD_INSTRUCTION nil crash iOS App Store rejection Guideline 2.1 -->

## Purpose
Detects force unwraps, force casts, force try, and other crash-prone Swift patterns that can cause unrecoverable crashes during App Store review, violating Guideline 2.1.

## Apple Guideline
- **Primary:** 2.1 — Performance: App Completeness (Crashes)
- **Related:** 2.1
- **Reference:** `references/guidelines/2-performance.md`

## Real-World Rejection Cases
- **Case:** Force unwrap crash on nil response — reviewer hit edge case with test data — rejected under 2.1
  **Source:** Apple Developer Forums (multiple threads on crash-related rejections)
  **Root cause:** Force unwrap (!) causes EXC_BAD_INSTRUCTION crash at review time on edge-case data — reviewers use test accounts and synthetic data that may produce nil where the developer did not expect it

- **Case:** Force cast `as!` crash when server returned unexpected type — reviewer triggered during review
  **Source:** Developer blogs
  **Root cause:** Casting without nil check produces unrecoverable crash — reviewers will encounter this on any data type mismatch between the server and the app's model layer

## Trigger
Invoke on any iOS/macOS Swift project before App Store submission to identify high-risk crash patterns.

## Inputs
| Name | Type | Default | Description |
|------|------|---------|-------------|
| `project_root` | path | cwd | iOS/macOS project root |
| `shared_context` | object | nil | Pre-collected context from appstore-full-audit Phase 1 |

## Actions

### Phase 1: Context Collection
*Skip this phase if `shared_context` is provided.*

1. `Glob` `**/*.swift` — collect all Swift source files.
2. `Glob` `**/*.m` — collect Objective-C source files.

### Phase 2: Checks

1. **Force unwrap**
   Run multiple `Grep` patterns in `**/*.swift` to catch all force-unwrap variants:
   - `[a-zA-Z0-9_]!\.[a-zA-Z]` — force unwrap before property/method access (`value!.property`)
   - `[a-zA-Z0-9_]! ` — force unwrap before space (`let x = value! `)
   - `[a-zA-Z0-9_]!,` — force unwrap in argument list (`foo(value!, other)`)
   - `[a-zA-Z0-9_]!\)` — force unwrap inside parentheses (`foo(value!)`)
   - `[a-zA-Z0-9_]!\]` — force unwrap before subscript (`arr[value!]`)
   - `[a-zA-Z0-9_]!$` — force unwrap at end of line (`let x = dict["key"]!`)
   Each match that is not in a test target or a SwiftUI `#Preview` block → 🔴 CRITICAL per occurrence. Replace with `if let`, `guard let`, or `??` fallback.

2. **Force cast**
   `Grep` pattern ` as! ` in `**/*.swift`.
   Each match not in a test file → 🔴 CRITICAL. Replace with `as?` and appropriate nil handling.

3. **Force try**
   `Grep` pattern `try!` in `**/*.swift`.
   Each match not in a test file → 🔴 CRITICAL. Replace with `do { try ... } catch { }` or `try?`.

4. **fatalError in non-exhaustive contexts**
   `Grep` pattern `fatalError\(` in `**/*.swift`.
   For each match, `Read` surrounding context — if used inside a `switch` for enum exhaustiveness or in `required init(coder:)` boilerplate stubs, flag → 🟠 HIGH. Any `fatalError` reachable at runtime on valid user input is a crash risk.

5. **UI updates on background thread**
   `Grep` pattern `DispatchQueue\.main\.async|DispatchQueue\.main\.sync` in `**/*.swift` — check for their absence near UI updates.
   Also `Grep` for `UILabel\.text\s*=|UIImageView\.image\s*=|tableView\.reloadData|collectionView\.reloadData` — if these appear outside a `DispatchQueue.main` block, flag → 🟠 HIGH. Background thread UI mutations cause runtime crashes that are difficult to reproduce but may surface during review.

### Phase 3: Output
Collect all findings from Phase 2 and build the prioritised findings list below. Include file paths and line numbers. Omit tiers with no findings.

## Output Format

```
## Crash Risk Audit — Findings

### 🔴 CRITICAL — Guaranteed rejection
- [ ] TODO: Replace force unwrap with guard let or if let — crash risk on nil value — `NetworkManager.swift:45` — Guideline 2.1
- [ ] TODO: Replace `as! UserModel` with `as? UserModel` and handle nil — force cast crash risk — `FeedViewController.swift:112` — Guideline 2.1
- [ ] TODO: Replace try! with do-catch or try? — unhandled error will crash — `DatabaseManager.swift:88` — Guideline 2.1

### 🟠 HIGH — Very likely rejection
- [ ] TODO: Wrap fatalError in required init(coder:) stub with assertionFailure or a logged fallback — `CustomView.swift:22` — Guideline 2.1
- [ ] TODO: Move UILabel.text update inside DispatchQueue.main.async — UI mutation on background thread detected — `DataViewModel.swift:67`

### 🟡 MEDIUM — Possible rejection
- [ ] TODO: Audit remaining fatalError calls to verify they cannot be reached on valid user data paths

### 🟢 LOW — Best practice
- [ ] TODO: Enable Swift strict concurrency checking (SWIFT_STRICT_CONCURRENCY = complete) to catch actor-isolation violations before submission
```

## Tools Used
`Glob`, `Grep`, `Read`

## Constraints
- Read-only. No file edits.
- No network calls.
- Skip Phase 1 if `shared_context` is provided by orchestrating agent.
- Works on Swift, Objective-C, React Native, Flutter projects.

## Quick Commands

Run these in your project root to check manually:

```bash
# Count force unwraps (!)
!grep -rn " as! \|try!" . --include="*.swift" | grep -v "//\|fatalError" | wc -l

# List force casts (review each one)
!grep -rn " as! " . --include="*.swift" | grep -v "//"

# Check for force try
!grep -rn "try!" . --include="*.swift" | grep -v "//"

# Check for fatalError usage
!grep -rn "fatalError\(" . --include="*.swift" | grep -v "//"
```

## Swift Anti-Pattern Reference
`examples/swift/QualityPatterns.swift`

## Detection Steps

1. **Find target files**
   - Glob: `**/*.swift` (exclude `*Tests*`, `*Spec*`, `*Mock*` paths)

2. **Search for rejection patterns**
   - Grep `\w![.(]` — force unwrap (`value!.property`, `value!(`) — avoids `!=` false positives
   - Grep `\bas!\b` — force cast
   - Grep `\btry!\b` — force try
   - Grep `fatalError\|preconditionFailure` — unconditional crash (flag in non-test files)
   - Grep `\.reloadData()\|\.reloadSections\|beginUpdates` — check surrounding context for DispatchQueue.main

3. **Determine verdict**
   - Force unwrap in production Swift file → 🟠 HIGH (Guideline 2.1)
   - Force cast in production Swift file → 🟠 HIGH
   - UITableView/UICollectionView reload outside `DispatchQueue.main` → 🔴 CRITICAL
   - `fatalError` reachable from normal user flow → 🟠 HIGH
   - No crash-risk patterns in production code → 🟢 pass

4. **Report**
   - File path + line number of each occurrence
   - Fix: Replace `value!` with `guard let value = value else { return }` or `if let`; wrap UI updates in `DispatchQueue.main.async { }`

Attribution

cruisediarycruisediary
View sourceMore from cruisediary →
SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

Related Skills

Caveman

Ultra-compressed communication mode that cuts output tokens while keeping technical accuracy. Levels: lite, full, ultra and the wenyan variants. Use for /caveman, "caveman mode", "talk like caveman", "be brief" or "less tokens".

1074701 votes

Hyperplan

Adversarial multi-agent planning skill. Self-orchestrates 5 hostile category members (unspecified-low, unspecified-high, deep, ultrabrain, artistry) via team-mode for ruthless cross-critique debate, distills only the defensible insights, then MANDATORILY hands the distilled insight bundle to the `plan` agent for executable plan formalization. Use when planning needs maximum rigor and surfacing of weak assumptions, blind spots, and over-engineering. Triggers: 'hyperplan', 'hpp', '/hyperplan', ...

693621 votes

Mcp Code Execution

Routes multi-tool workflows through MCP servers for large datasets and pipelines. Use when Bash tool overhead is limiting throughput on data-heavy tasks.

3351 votes

catchup

Recovers the conversation and failed tool calls of a previous Codex, Claude Code, Antigravity, Cline, Copilot CLI, Cursor, DeepSeek Harness, Kimi, OpenCode, Pi Agent, or ZCode session. Use when the user says "catch up", "what did the last session do", "get me up to speed", "I switched agents", asks to recover/summarize a previous session before continuing, or asks to diagnose or report a catchup failure. Do NOT use for the current conversation, git history, or any non-agent log.

691 votes

math-skill

A comprehensive mathematical reasoning skill for AI assistants — handles arithmetic to research-level problems with rigorous step-by-step reasoning, systematic verification, and transparent uncertainty handling

381 votes
View all in ai-agents →