debug:flutter
Debug Flutter applications systematically with this comprehensive troubleshooting skill. Covers RenderFlex overflow errors, setState() after dispose() issues, null check operator failures, platform channel problems, build context errors, and hot reload failures. Provides structured four-phase debugging methodology with Flutter DevTools, widget inspector, performance profiling, and platform-specific debugging for Android, iOS, and web targets.
What this skill does
# Flutter Debugging Guide
This skill provides a systematic approach to debugging Flutter applications, covering common error patterns, debugging tools, and best practices for efficient problem resolution.
## Common Error Patterns
### 1. RenderFlex Overflow Error
**Symptoms:**
- Yellow and black stripes appear in the UI indicating overflow area
- Error message: "A RenderFlex overflowed by X pixels"
**Causes:**
- Content exceeds available space in Row/Column
- Fixed-size widgets in constrained containers
- Text without proper overflow handling
**Solutions:**
```dart
// Solution 1: Wrap in SingleChildScrollView
SingleChildScrollView(
child: Column(
children: [...],
),
)
// Solution 2: Use Flexible or Expanded
Row(
children: [
Expanded(
child: Text('Long text that might overflow...'),
),
],
)
// Solution 3: Handle text overflow explicitly
Text(
'Long text...',
overflow: TextOverflow.ellipsis,
maxLines: 2,
)
```
### 2. setState() Called After Dispose
**Symptoms:**
- Runtime error: "setState() called after dispose()"
- App crashes after async operations complete
**Causes:**
- Calling setState() after widget is removed from tree
- Async operations completing after navigation away
- Timer callbacks on disposed widgets
**Solutions:**
```dart
// Solution 1: Check mounted before setState
Future<void> fetchData() async {
final data = await api.getData();
if (mounted) {
setState(() {
_data = data;
});
}
}
// Solution 2: Cancel async operations in dispose
late final StreamSubscription _subscription;
@override
void dispose() {
_subscription.cancel();
super.dispose();
}
// Solution 3: Use CancelableOperation
CancelableOperation<Data>? _operation;
Future<void> fetchData() async {
_operation = CancelableOperation.fromFuture(api.getData());
final data = await _operation!.value;
if (mounted) {
setState(() => _data = data);
}
}
@override
void dispose() {
_operation?.cancel();
super.dispose();
}
```
### 3. Null Check Operator Errors
**Symptoms:**
- Error: "Null check operator used on a null value"
- App crashes when accessing nullable values with `!`
**Causes:**
- Using `!` operator on null values
- Not initializing late variables
- Race conditions in async code
**Solutions:**
```dart
// Bad: Using ! without null check
final name = user!.name;
// Good: Use null-aware operators
final name = user?.name ?? 'Unknown';
// Good: Use if-null check
if (user != null) {
final name = user.name;
}
// Good: Use pattern matching (Dart 3+)
if (user case final u?) {
final name = u.name;
}
// For late initialization, consider nullable with check
String? _data;
String get data {
if (_data == null) {
throw StateError('Data not initialized');
}
return _data!;
}
```
### 4. Platform Channel Issues
**Symptoms:**
- MissingPluginException
- PlatformException with native code errors
- Method channel not responding
**Solutions:**
```dart
// Solution 1: Ensure proper platform setup
// Run flutter clean && flutter pub get
// Solution 2: Check method channel registration
const platform = MethodChannel('com.example/channel');
try {
final result = await platform.invokeMethod('methodName');
} on PlatformException catch (e) {
debugPrint('Platform error: ${e.message}');
} on MissingPluginException {
debugPrint('Plugin not registered for this platform');
}
// Solution 3: For plugins, ensure proper initialization
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Initialize plugins here
runApp(MyApp());
}
```
### 5. Build Context Errors
**Symptoms:**
- "Looking up a deactivated widget's ancestor is unsafe"
- Navigator operations fail
- Theme/MediaQuery not available
**Causes:**
- Using context after widget disposal
- Using context in initState before build
- Storing context references
**Solutions:**
```dart
// Bad: Using context in initState
@override
void initState() {
super.initState();
// Theme.of(context); // Error!
}
// Good: Use didChangeDependencies
@override
void didChangeDependencies() {
super.didChangeDependencies();
final theme = Theme.of(context);
}
// Good: Use Builder for nested contexts
Scaffold(
body: Builder(
builder: (context) {
// This context has access to Scaffold
return ElevatedButton(
onPressed: () {
Scaffold.of(context).showSnackBar(...);
},
child: Text('Show Snackbar'),
);
},
),
)
// Good: Use GlobalKey for cross-widget access
final scaffoldKey = GlobalKey<ScaffoldState>();
```
### 6. Hot Reload Failures
**Symptoms:**
- Changes not reflecting after save
- App state lost unexpectedly
- "Hot reload not available" message
**Causes:**
- Changing app initialization code
- Modifying const constructors
- Native code changes
- Global variable mutations
**Solutions:**
```bash
# Solution 1: Hot restart instead of hot reload
# Press 'R' (capital) in terminal or Shift+Cmd+\ in VS Code
# Solution 2: Full restart
flutter run --no-hot
# Solution 3: Clean build
flutter clean && flutter pub get && flutter run
```
**Code patterns that require hot restart:**
```dart
// Changes to main() require restart
void main() {
runApp(MyApp()); // Modification here needs restart
}
// Changes to initState logic often need restart
@override
void initState() {
super.initState();
_controller = AnimationController(...); // Changes here need restart
}
// Const constructor changes need restart
const MyWidget({super.key}); // Adding/removing const needs restart
```
### 7. Vertical Viewport Given Unbounded Height
**Symptoms:**
- Error: "Vertical viewport was given unbounded height"
- ListView inside Column fails
**Solutions:**
```dart
// Bad: ListView in Column without constraints
Column(
children: [
ListView(...), // Error!
],
)
// Good: Use Expanded
Column(
children: [
Expanded(
child: ListView(...),
),
],
)
// Good: Use shrinkWrap (for small lists only)
Column(
children: [
ListView(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
children: [...],
),
],
)
// Good: Use SizedBox with fixed height
Column(
children: [
SizedBox(
height: 200,
child: ListView(...),
),
],
)
```
### 8. RenderBox Was Not Laid Out
**Symptoms:**
- Error: "RenderBox was not laid out"
- Widget fails to render
**Solutions:**
```dart
// Ensure parent provides constraints
SizedBox(
width: 200,
height: 200,
child: CustomPaint(...),
)
// For intrinsic sizing
IntrinsicHeight(
child: Row(
children: [
Container(color: Colors.red),
Container(color: Colors.blue),
],
),
)
```
### 9. Incorrect Use of ParentDataWidget
**Symptoms:**
- Error: "Incorrect use of ParentDataWidget"
- Positioned/Expanded used incorrectly
**Solutions:**
```dart
// Bad: Positioned outside Stack
Column(
children: [
Positioned(...), // Error!
],
)
// Good: Positioned inside Stack
Stack(
children: [
Positioned(
top: 10,
left: 10,
child: Text('Hello'),
),
],
)
// Bad: Expanded outside Flex widget
Container(
child: Expanded(...), // Error!
)
// Good: Expanded inside Row/Column
Row(
children: [
Expanded(child: Text('Hello')),
],
)
```
### 10. Red/Grey Screen of Death
**Symptoms:**
- Red screen in debug/profile mode
- Grey screen in release mode
- App appears frozen
**Causes:**
- Uncaught exceptions
- Rendering errors
- Failed assertions
**Solutions:**
```dart
// Global error handling
void main() {
FlutterError.onError = (details) {
FlutterError.presentError(details);
// Log to crash reporting service
crashReporter.recordFlutterError(details);
};
PlatformDispatcher.instance.onError = (error, stack) {
// Handle async errors
crashReporter.recordError(error, stack);
return true;
};
runApp(MyApp());
}
// Custom error widget
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
ErrorWidget.builder = (FluRelated in Code Review
gstack
IncludedFast headless browser for QA testing and site dogfooding. Navigate pages, interact with elements, verify state, diff before/after, take annotated screenshots, test responsive layouts, forms, uploads, dialogs, and capture bug evidence. Use when asked to open or test a site, verify a deployment, dogfood a user flow, or file a bug with screenshots. (gstack)
startup-due-diligence
IncludedLegal due diligence review for seed-stage and Series A startups (US, Delaware C-Corp focus). Supports both investor and founder perspectives. Capabilities include: (1) Interactive document review and issue spotting; (2) Document request list generation; (3) Cap table and SAFE/convertible note analysis; (4) Red flag identification with severity ratings; (5) Diligence report generation. TRIGGERS: due diligence, DD, startup investment, cap table review, Series A, seed round, investor diligence, legal review startup, SAFE analysis, convertible note, 409A, founder vesting.
interview-master
IncludedThis skill should be used when the user asks to "generate interview questions", "prepare for interview", "optimize resume", "conduct mock interview", "analyze git commits for resume", "generate resume from code", "review my resume", or mentions interview preparation, career assistance, or extracting project experience from git history. Provides comprehensive interview and career development guidance for both job seekers and interviewers.
fix-issue
IncludedFixes GitHub issues using parallel analysis agents for root cause investigation, code exploration, and regression detection. Reads issue context from gh CLI, searches codebase and memory for related patterns, generates a fix with tests, and links the resolution back to the issue via PR. Includes prevention analysis to avoid recurrence. Use when debugging errors, resolving regressions, fixing bugs, or triaging issues.
sf-apex
IncludedGenerates and reviews Salesforce Apex code with 150-point scoring. TRIGGER when: user writes, reviews, or fixes Apex classes, triggers, test classes, batch/queueable/schedulable jobs, or touches .cls/.trigger files. DO NOT TRIGGER when: LWC JavaScript (use sf-lwc), Flow XML (use sf-flow), SOQL-only queries (use sf-soql), or non-Salesforce code.
swift-development
IncludedComprehensive Swift development for building, testing, and deploying iOS/macOS applications. Use when Claude needs to: (1) Build Swift packages or Xcode projects from command line, (2) Run tests with XCTest or Swift Testing framework, (3) Manage iOS simulators with simctl, (4) Handle code signing, provisioning profiles, and app distribution, (5) Format or lint Swift code with SwiftFormat/SwiftLint, (6) Work with Swift Package Manager (SPM), (7) Implement Swift 6 concurrency patterns (async/await, actors, Sendable), (8) Create SwiftUI views with MVVM architecture, (9) Set up Core Data or SwiftData persistence, or any other Swift/iOS/macOS development tasks.