This template guides you through fixing bugs in existing widgets following established patterns and ensuring no regressions.
Purpose: Systematic approach to bug fixes
Scope: Widgets, components, hooks, store integration
- Reported bug in existing widget
- UI not rendering correctly
- Callbacks not firing
- Store integration issues
- Performance problems
- Test failures
- Which widget/component has the bug? _______________
- Bug description (one sentence): _______________
- Steps to reproduce:
-
- Expected behavior: _______________
- Actual behavior: _______________
-
Which layer is affected?
- Widget component
- Hook (helper.ts)
- Presentational component
- Store integration
- SDK integration
-
Error messages:
- Console errors: _______________
- Linter errors: _______________
- Test failures: _______________
- Severity: Critical / High / Medium / Low
- User Impact: _______________
- Affects other widgets? Yes / No
- If yes, which ones: _______________
- Is there a workaround? Yes / No
- If yes, describe: _______________
- Is there a test for this scenario? Yes / No
- Are tests failing? Yes / No
- Test file location: _______________
// Create minimal reproduction
// 1. Set up component
// 2. Trigger the bug
// 3. Observe the issueReproduction confirmed: Yes / No
Read relevant files:
- Widget component:
src/{widget-name}/index.tsx - Hook:
src/helper.ts - Presentational component: Check cc-components
- Store: Check store integration
- Types:
src/{widget-name}/{widget-name}.types.ts
Check for:
- Missing null/undefined checks
- Incorrect MobX usage (missing observer, runInAction)
- Wrong prop types
- Missing error boundaries
- Race conditions
- Memory leaks
- Event listener issues
Root cause: _______________
Architecture check:
✅ Widget → Hook → Component → Store → SDK
❌ Widget → SDK (layer violation)
❌ Component → Store (layer violation)
Is there a layer violation? Yes / No
- If yes, this is likely the root cause
Choose approach:
- Defensive Fix: Add null checks, error handling
- Refactor Fix: Restructure code to prevent issue
- Pattern Fix: Apply correct pattern (MobX, React)
- Integration Fix: Fix store/SDK integration
- Type Fix: Add/fix TypeScript types
Fix description: _______________
List all files that need changes:
-
src/{widget-name}/index.tsx -
src/helper.ts -
src/{widget-name}/{widget-name}.types.ts -
tests/{widget-name}/index.tsx -
tests/helper.ts -
ai-docs/ARCHITECTURE.md - Other: _______________
Will this fix break existing functionality? Yes / No
If Yes:
- Document breaking change
- Update version (major/minor)
- Update migration guide
File: src/{widget-name}/index.tsx
Common fixes:
// Fix 1: Add null checks
const {WidgetName}Internal: React.FC<Props> = observer((props) => {
const { data } = useHook(props);
// ✅ Add null check
if (!data) {
return <div>Loading...</div>;
}
return <Component data={data} />;
});// Fix 2: Add error boundary
<ErrorBoundary
fallback={<div>Error occurred</div>}
onError={(error) => {
console.error('Widget Error:', error);
props.onError?.(error); // Notify parent
}}
>
<{WidgetName}Internal {...props} />
</ErrorBoundary>// Fix 3: Fix observer HOC
// ❌ Wrong
const Widget = (props) => { ... };
// ✅ Correct
const Widget = observer((props) => { ... });File: src/helper.ts
Common fixes:
// Fix 1: Add proper cleanup
useEffect(() => {
const subscription = store.cc.on('event', handler);
// ✅ Add cleanup
return () => {
subscription.unsubscribe();
};
}, []);// Fix 2: Fix runInAction usage
// ❌ Wrong
const handler = () => {
store.setSomeValue(newValue); // Direct mutation
};
// ✅ Correct
const handler = () => {
runInAction(() => {
store.setSomeValue(newValue);
});
};// Fix 3: Fix dependency array
// ❌ Wrong - missing dependency
useCallback(() => {
doSomething(props.value);
}, []); // Missing props.value
// ✅ Correct
useCallback(() => {
doSomething(props.value);
}, [props.value]);// Fix 4: Add error handling
const fetchData = useCallback(async () => {
try {
const result = await store.cc.someMethod();
setData(result);
} catch (error) {
setError(error as Error);
props.onError?.(error as Error); // Notify parent
}
}, [props]);File: cc-components component
Common fixes:
// Fix 1: Fix prop destructuring
// ❌ Wrong - missing default
const Component: React.FC<Props> = ({ items }) => {
return items.map(...); // Crashes if undefined
};
// ✅ Correct
const Component: React.FC<Props> = ({ items = [] }) => {
return items.map(...);
};// Fix 2: Fix event handler
// ❌ Wrong - inline function creates new reference
<Button onClick={() => props.onAction(data)}>
// ✅ Correct - use useCallback
const handleClick = useCallback(() => {
props.onAction(data);
}, [props.onAction, data]);
<Button onClick={handleClick}>File: src/{widget-name}/{widget-name}.types.ts
// Fix 1: Make prop optional if it can be undefined
export interface WidgetProps {
// ❌ Wrong - marked required but can be undefined
data: SomeType;
// ✅ Correct
data?: SomeType;
}// Fix 2: Add missing types
export interface WidgetProps {
onEvent: (data: any) => void; // ❌ any is too loose
onEvent: (data: EventData) => void; // ✅ Proper type
}File: tests/{widget-name}/index.tsx
// Add test that reproduces the bug
describe('{WidgetName} - Bug Fix', () => {
it('should handle {bug scenario}', async () => {
// Setup: Create conditions that trigger bug
const props = {
// Props that trigger bug
};
render(<{WidgetName} {...props} />);
// Action: Trigger the bug
fireEvent.click(screen.getByRole('button'));
// Assert: Bug is fixed
await waitFor(() => {
expect(screen.queryByText('Error')).not.toBeInTheDocument();
expect(screen.getByText('Expected')).toBeInTheDocument();
});
});
});// If fix changes behavior, update tests
it('existing test that needs update', () => {
// Update assertions to match new behavior
});# Run unit tests
cd packages/contact-center/{widget-name}
yarn test:unit
# Run linting
yarn test:styles
# Run E2E tests (if applicable)
cd ../../../
yarn test:e2eAll tests pass: Yes / No
- If no, fix failing tests or code
File: ai-docs/ARCHITECTURE.md
Update if:
- Data flow changed
- New error handling added
- Sequence diagram affected
Add to troubleshooting:
#### {Issue Number}. {Bug Title}
**Symptoms:**
- {What users saw}
**Possible Causes:**
- {Root cause}
**Solutions:**
```typescript
// Fixed code examplePrevention:
- {How to avoid}
### 5.2 Update AGENTS.md (if needed)
**File:** `ai-docs/AGENTS.md`
**Update if:**
- API changed
- New examples needed
- Usage pattern changed
---
## Step 6: Validation
### 6.1 Code Quality Checks
- [ ] Follows [TypeScript Patterns](../../patterns/typescript-patterns.md)
- [ ] Follows [React Patterns](../../patterns/react-patterns.md)
- [ ] Follows [MobX Patterns](../../patterns/mobx-patterns.md)
- [ ] No layer violations
- [ ] Error handling in place
- [ ] Proper cleanup (useEffect)
### 6.2 Testing Checks
- [ ] Bug reproduced before fix
- [ ] Fix resolves the bug
- [ ] Regression test added
- [ ] All tests pass
- [ ] No new test failures
- [ ] Linting passes
- [ ] Build succeeds
### 6.3 Integration Checks
- [ ] Widget works in React sample
- [ ] Widget works in WC sample
- [ ] No console errors
- [ ] No console warnings
- [ ] Callbacks fire correctly
- [ ] Store integration works
### 6.4 Documentation Checks
- [ ] ARCHITECTURE.md updated (if needed)
- [ ] AGENTS.md updated (if needed)
- [ ] Troubleshooting guide updated
- [ ] CHANGELOG updated
### 6.5 Manual Testing
- [ ] Bug is fixed
- [ ] No regression in other features
- [ ] Edge cases handled
- [ ] Error states work
- [ ] Performance not degraded
---
## Common Bug Patterns & Fixes
### Pattern 1: Missing Null Checks
**Bug:**
```typescript
const Component = ({ data }) => {
return <div>{data.name}</div>; // Crashes if data is null
};
Fix:
const Component = ({ data }) => {
if (!data) return <div>No data</div>;
return <div>{data.name}</div>;
};Bug:
const Widget = (props) => {
const storeValue = store.observable; // Doesn't react to changes
return <div>{storeValue}</div>;
};Fix:
const Widget = observer((props) => {
const storeValue = store.observable; // Now reacts to changes
return <div>{storeValue}</div>;
});Bug:
const handler = () => {
store.setValue(newValue); // MobX warning
};Fix:
const handler = () => {
runInAction(() => {
store.setValue(newValue);
});
};Bug:
useEffect(() => {
const subscription = store.cc.on('event', handler);
// No cleanup - memory leak
}, []);Fix:
useEffect(() => {
const subscription = store.cc.on('event', handler);
return () => subscription.unsubscribe(); // Cleanup
}, []);Bug:
useCallback(() => {
doSomething(props.value);
}, []); // Missing dependencyFix:
useCallback(() => {
doSomething(props.value);
}, [props.value]); // Correct dependenciesBug:
// Widget directly calls SDK
const Widget = () => {
const handleClick = () => {
store.cc.someMethod(); // Layer violation
};
// ...
};Fix:
// Widget → Hook → SDK
const Widget = () => {
const { handleClick } = useWidget(); // Hook handles SDK
// ...
};
// In helper.ts
const handleClick = useCallback(() => {
store.cc.someMethod(); // Correct layer
}, []);- feature-enhancement.md - Add features to existing widgets
- ../documentation/create-agent-md.md - Documentation template
Template Version: 1.0.0 Last Updated: 2025-11-26