Symptom-based troubleshooting for background task issues.
Works with
AI-first code editor with Composer
Before installing skills in Cursor, ensure your development environment meets these requirements:
node --versionaxiom-background-processing-diagExecute the skills CLI command in your project's root directory to begin installation:
Fetches axiom-background-processing-diag from charleswiltgen/axiom and configures it for Cursor.
The CLI shows a list of agents. Use arrow keys and space to select Cursor:
Confirm successful installation by checking the skill directory location:
Restart Cursor to activate axiom-background-processing-diag. Access via /axiom-background-processing-diag in your agent's command palette.
We perform automated surface-level scans (Gen AI Scanner, Socket, Snyk) during installation. These checks detect common vulnerabilities but do not guarantee complete security. Always review skill source code and verify the publisher's reputation before production use.
Skills execute code in your environment. Always review source, verify the publisher, and test in isolation before production.
Submit your Claude Code skill and start earning
Create detailed user stories, acceptance criteria, and feature specs
Example
Generate user stories for 'password reset feature' with acceptance criteria, edge cases, and test scenarios
Reduce spec writing time by 50%, ensure comprehensive coverage
Research competitors, compare features, identify gaps
Example
Analyze 5 competitor products, create feature comparison matrix, suggest differentiation opportunities
Complete competitive research in 2 hours instead of 2 days
Evaluate features using frameworks (RICE, ICE, Kano) and create prioritized backlogs
Example
Score 20 feature ideas using RICE framework, generate prioritized roadmap with rationale
0
total installs
0
this week
767
GitHub stars
0
upvotes
Run in your terminal
0
installs
0
this week
767
stars
Symptom-based troubleshooting for background task issues.
Related skills: axiom-background-processing (patterns, checklists), axiom-background-processing-ref (API reference)
Handler never called despite successful submit().
Task never runs?
│
├─ Step 1: Check Info.plist (2 min)
│ ├─ BGTaskSchedulerPermittedIdentifiers contains EXACT identifier?
│ │ └─ NO → Add identifier, rebuild
│ ├─ UIBackgroundModes includes "fetch" or "processing"?
│ │ └─ NO → Add required mode
│ └─ Identifiers case-sensitive match code?
│ └─ NO → Fix typo, rebuild
│
├─ Step 2: Check registration timing (2 min)
│ ├─ Registered in didFinishLaunchingWithOptions?
│ │ └─ NO → Move registration before return true
│ └─ Registration before first submit()?
│ └─ NO → Ensure register() precedes submit()
│
└─ Step 3: Check app state (1 min)
├─ App swiped away from App Switcher?
│ └─ YES → No background until user opens app
└─ Background App Refresh disabled in Settings?
└─ YES → Enable or inform user
| Approach | Time | Success Rate |
|---|---|---|
| Check Info.plist + registration | 5 min | 70% (catches most issues) |
| Add console logging | 15 min | 90% |
| LLDB simulate launch | 5 min | 95% (confirms handler works) |
| Random code changes | 2+ hours | Low |
Verify handler is correctly registered:
e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.yourapp.refresh"]
If breakpoint hits → Registration correct, issue is scheduling/system factors. If nothing happens → Registration broken.
Handler called but work doesn't complete before termination.
Task terminates early?
│
├─ Step 1: Check expiration handler (1 min)
│ ├─ Expiration handler set FIRST in handler?
│ │ └─ NO → Move to very first line
│ └─ Expiration handler actually cancels work?
│ └─ NO → Add cancellation logic
│
├─ Step 2: Check setTaskCompleted (2 min)
│ ├─ Called in success path?
│ ├─ Called in failure path?
│ ├─ Called after expiration?
│ └─ ANY path missing → Task never signals completion
│
├─ Step 3: Check work duration (2 min)
│ ├─ BGAppRefreshTask work > 30 seconds?
│ │ └─ YES → Chunk work or use BGProcessingTask
│ └─ BGProcessingTask work > system limit?
│ └─ YES → Save progress, resume on next launch
| Cause | Fix |
|---|---|
| Missing expiration handler | Set handler as first line |
| setTaskCompleted not called | Add to ALL code paths |
| Work takes too long | Chunk and checkpoint |
| Network timeout > task time | Use background URLSession |
| Async callback after expiration | Check shouldContinue flag |
// First simulate launch
e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.yourapp.refresh"]
// Then force expiration
e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateExpirationForTaskWithIdentifier:@"com.yourapp.refresh"]
Verify expiration handler runs and work stops gracefully.
Download completes but didFinishDownloadingTo never fires.
URLSession delegate not called?
│
├─ Step 1: Check session configuration (2 min)
│ ├─ Using URLSessionConfiguration.background()?
│ │ └─ NO → Must use background config
│ ├─ Session identifier unique?
│ │ └─ NO → Use unique bundle-prefixed ID
│ └─ sessionSendsLaunchEvents = true?
│ └─ NO → Set for app relaunch on completion
│
├─ Step 2: Check AppDelegate handler (2 min)
│ ├─ handleEventsForBackgroundURLSession implemented?
│ │ └─ NO → Required for session events
│ └─ Completion handler stored and called later?
│ └─ NO → Store handler, call after events processed
│
└─ Step 3: Check delegate assignment (1 min)
├─ Session created with delegate?
└─ Delegate not nil when task completes?
// Store completion handler
var backgroundSessionCompletionHandler: (() -> Void)?
func application(_ application: UIApplication,
handleEventsForBackgroundURLSession identifier: String,
completionHandler: @escaping () -> Void) {
backgroundSessionCompletionHandler = completionHandler
}
// Call after all events processed
func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
DispatchQueue.main.async {
self.backgroundSessionCompletionHandler?()
self.backgroundSessionCompletionHandler = nil
}
}
Task runs with debugger but fails in release builds or for users.
Works in dev, not prod?
│
├─ Step 1: Check system constraints (3 min)
│ ├─ Low Power Mode enabled?
│ │ └─ Check ProcessInfo.isLowPowerModeEnabled
│ ├─ Background App Refresh disabled?
│ │ └─ Check UIApplication.backgroundRefreshStatus
│ └─ Battery < 20%?
│ └─ System pauses discretionary work
│
├─ Step 2: Check app state (2 min)
│ ├─ App force-quit from App Switcher?
│ │ └─ YES → No background until foreground launch
│ └─ App recently used?
│ └─ Rarely used apps get lower priority
│
├─ Step 3: Check build differences (3 min)
│ ├─ Debug vs Release optimization differences?
│ ├─ #if DEBUG code excluding production?
│ └─ Different bundle identifier in release?
│
└─ Step 4: Add production logging (2 min)
└─ Log task schedule/launch/complete to analytics
All affect task execution in production:
| Factor | Check |
|---|---|
| Critically Low Battery | Battery < 20%? |
| Low Power Mode | ProcessInfo.isLowPowerModeEnabled |
| App Usage | User opens app frequently? |
| App Switcher | App NOT swiped away? |
| Background App Refresh | Settings enabled? |
| System Budgets | Many recent background launches? |
| Rate Limiting | Requests too frequent? |
Add logging to track what's happening:
func scheduleRefresh() {
let request = BGAppRefreshTaskRequest(identifier: "com.app.refresh")
do {
try BGTaskScheduler.shared.submit(request)
Analytics.log("background_task_scheduled")
} catch {
Analytics.log("background_task_schedule_failed", error: error)
}
}
func handleRefresh(task: BGAppRefreshTask) {
Analytics.log("background_task_started")
// ... work ...
Analytics.log("background_task_completed")
task.setTaskCompleted(success: true)
}
Task runs sometimes but not predictably.
Inconsistent scheduling?
│
├─ Step 1: Understand earliestBeginDate (2 min)
│ ├─ This is MINIMUM delay, not scheduled time
│ │ └─ System runs when convenient AFTER this date
│ └─ Set too far in future (> 1 week)?
│ └─ System may skip task entirely
│
├─ Step 2: Check scheduling pattern (2 min)
│ ├─ Scheduling same task multiple times?
│ │ └─ Call getPendingTaskRequests to check
│ └─ Scheduling in handler for continuity?
│ └─ Required for continuous refresh
│
└─ Step 3: Understand system behavior (1 min)
├─ BGAppRefreshTask runs based on USER patterns
│ └─ User rarely opens app = rare runs
└─ BGProcessingTask runs when charging
└─ User doesn't charge overnight = no runs
| Task Type | Scheduling Behavior |
|---|---|
| BGAppRefreshTask | Runs before predicted app usage times |
| BGProcessingTask | Runs when charging + idle (typically overnight) |
| Silent Push | Rate-limited; 14 pushes may = 7 launches |
Key insight: You request a time window. System decides when (or if) to run.
App crashes when launched by system for background task.
Crash on background launch?
│
├─ Step 1: Check launch initialization (2 min)
│ ├─ UI setup before task handler?
│ │ └─ Background launch may not have UI context
│ ├─ Accessing files before first unlock?
│ │ └─ Use completeUntilFirstUserAuthentication protection
│ └─ Force unwrapping optionals that may be nil?
│ └─ Guard against nil in background context
│
├─ Step 2: Check handler safety (2 min)
│ ├─ Handler captures self strongly?
│ │ └─ Use [weak self] to prevent retain cycles
│ └─ Handler accesses UI on non-main thread?
│ └─ Dispatch UI work to main queue
│
└─ Step 3: Check data protection (1 min)
└─ Files accessible when device locked?
└─ Use .completeUnlessOpen or .completeUntilFirstUserAuthentication
// Set appropriate protection when creating files
try data.write(to: url, options: .completeFileProtectionUntilFirstUserAuthentication)
// Or configure in entitlements for entire app
BGTaskScheduler.shared.register(
forTaskWithIdentifier: "com.app.refresh",
using: nil
) { [weak self] task in
guard let self = self else {
task.setTaskCompleted(success: false)
return
}
// Don't access UI
// Use background-safe APIs only
self.performBackgroundWork(task: task)
}
Same task appears to run repeatedly or in parallel.
Task runs multiple times?
│
├─ Step 1: Check scheduling logic (2 min)
│ ├─ Scheduling on every app launch?
│ │ └─ CMake data-driven prioritization decisions faster
Draft PRDs, status updates, and stakeholder presentations
Example
Create executive summary of Q3 roadmap, monthly progress report, feature launch announcement
Save 3-5 hours/week on communication overhead
Prerequisites
Time Estimate
30-60 minutes to see productivity improvements
Steps
Common Pitfalls
✓ Do
✗ Don't
💡 Pro Tips
✓ Use when
Use for user story writing, competitive research, roadmap prioritization, stakeholder communication, and PRD drafting. Best for reducing repetitive documentation and research work.
✗ Avoid when
Avoid for strategic product vision (requires deep customer empathy), pricing decisions (needs market and financial expertise), or when face-to-face customer discovery is more valuable than speed.
mattpocock/skills
parcadei/continuous-claude-v3
cursor/plugins
ailabs-393/ai-labs-claude-skills
pproenca/dot-skills
mattpocock/skills
I recommend axiom-background-processing-diag for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.
axiom-background-processing-diag fits our agent workflows well — practical, well scoped, and easy to wire into existing repos.
axiom-background-processing-diag is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.
Keeps context tight: axiom-background-processing-diag is the kind of skill you can hand to a new teammate without a long onboarding doc.
Keeps context tight: axiom-background-processing-diag is the kind of skill you can hand to a new teammate without a long onboarding doc.
axiom-background-processing-diag fits our agent workflows well — practical, well scoped, and easy to wire into existing repos.
axiom-background-processing-diag is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.
axiom-background-processing-diag is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.
axiom-background-processing-diag fits our agent workflows well — practical, well scoped, and easy to wire into existing repos.
I recommend axiom-background-processing-diag for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.
showing 1-10 of 65