{r.name}
);
}
// Understand why results might be undefined
// Is it during initial render? Is the API call failing?
// Then apply the appropriate fix with intention
function displayResults(results) {
// Deliberate decision: show loading state instead of crashing
if (!results) {
return Loading...
;
}
return results.map(r => {r.name}
);
}
```
**Action Item:** Before asking AI to fix a bug, spend 5 minutes investigating it yourself. You'll learn more and give better context to the AI.
## Ignoring Project Context and Conventions
AI doesn't know your team's coding standards, your project's architecture, or your established patterns. New vibe coders often let AI introduce inconsistencies.
**The Problem:**
Your project uses async/await everywhere, but the AI generates Promise chains. Your team uses functional components in React, but AI suggests a class component. You use camelCase, AI provides snake_case.
**Example:**
```python
# Your project's established pattern
class UserService:
def __init__(self, db_connection):
self.db = db_connection
async def get_user_by_id(self, user_id: int) -> Optional[User]:
# Uses async/await consistently
return await self.db.fetch_one(...)
# AI generates this for a new method:
def get_user_by_email(self, email):
# Different style: no type hints, no async, different naming
return self.db.fetchOne({"email": email})
```
**How to Fix It:**
Prime the AI with your project's context. Include existing code samples in your prompts.
**Better Prompt:**
```
Here's an example method from our UserService class:
async def get_user_by_id(self, user_id: int) -> Optional[User]:
query = "SELECT * FROM users WHERE id = ?"
return await self.db.fetch_one(query, [user_id])
Following this exact pattern and style, create a method to get a user by email address.
```
Now the AI will match your conventions.
**Action Item:** Create a project "style guide" snippet you can include in prompts for consistency. Update it as patterns emerge.
## Not Knowing When to Stop Using AI
This connects directly to our [when-not-to-use-ai](/lessons/when-not-to-use-ai) lesson. New vibe coders sometimes force AI into situations where manual coding is faster and clearer.
**When AI Slows You Down:**
- **Simple CRUD operations you've written 100 times**: Just write it. You'll be done faster than crafting a prompt.
- **Highly domain-specific logic**: If it requires deep business context, you'll spend more time explaining than coding.
- **One-line fixes**: Don't prompt AI to change a variable name or add a semicolon.
**Example of AI Overuse:**
```javascript
// Asking AI to: "Add a console.log statement to debug this"
// When you could just type:
console.log('User data:', userData);
// In 2 seconds flat
```
**How to Fix It:**
Develop a sense for when AI adds value versus when it's overhead. Generally:
- **Good AI use**: Boilerplate, unfamiliar libraries, complex logic, refactoring, test generation
- **Poor AI use**: Trivial edits, simple fixes, code you could write in your sleep
**Action Item:** Track your time for a week. Note when using AI saved time versus when it added friction. Adjust accordingly.
## Forgetting to Iterate and Refine
AI rarely nails it on the first try. New vibe coders accept the first output instead of refining it through conversation.
**The Problem:**
```python
# First AI output for "create a function to parse dates"
def parse_date(date_string):
return datetime.strptime(date_string, '%Y-%m-%d')
```
This works for one format, but what if your data has multiple formats? What about error handling?
**How to Fix It:**
Think of AI collaboration as a conversation. Iterate.
**Better Workflow:**
```
You: "Create a function to parse dates"
AI: [generates basic version]
You: "Now handle multiple formats: YYYY-MM-DD, MM/DD/YYYY, and DD-MM-YYYY"
AI: [adds format detection]
You: "Add error handling that returns None for invalid dates instead of raising exceptions"
AI: [adds try/except]
You: "Add a docstring with examples"
AI: [completes the function]
```
Final result:
```python
def parse_date(date_string: str) -> Optional[datetime]:
"""
Parse a date string in multiple common formats.
Supported formats:
- YYYY-MM-DD (e.g., "2024-01-15")
- MM/DD/YYYY (e.g., "01/15/2024")
- DD-MM-YYYY (e.g., "15-01-2024")
Returns None if date_string cannot be parsed.
Examples:
>>> parse_date("2024-01-15")
datetime.datetime(2024, 1, 15, 0, 0)
>>> parse_date("invalid")
None
"""
formats = ['%Y-%m-%d', '%m/%d/%Y', '%d-%m-%Y']
for fmt in formats:
try:
return datetime.strptime(date_string, fmt)
except ValueError:
continue
return None
```
**Action Item:** Never accept the first output as final. Always ask yourself: "What's missing? What could break? How can this be clearer?"
## Not Building Your Own Understanding
The ultimate mistake: letting AI knowledge replace your own learning. You can generate code without understanding it, but you can't maintain or debug it effectively.
**The Problem:**
You use AI to implement authentication, API integration, or state management without understanding the underlying concepts. When something breaks, you're helpless.
**How to Fix It:**
Use AI as a learning tool, not a black box. After generating code, research the concepts.
**Learning Workflow:**
1. Generate code with AI
2. Identify unfamiliar concepts or patterns
3. Research them independently
4. Experiment with variations manually
5. Now you own that knowledge
**Example:**
```javascript
// AI generates this React hook
function useDebounce(value, delay) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => {
clearTimeout(handler);
};
}, [value, delay]);
return debouncedValue;
}
```
**Don't just use it. Understand it:**
- What's debouncing and why is it useful?
- How does `useEffect` cleanup work?
- Why do we need `value` and `delay` in the dependency array?
- What happens if we remove the cleanup function?
**Action Item:** For every significant piece of AI-generated code, write a comment explaining what it does in your own words. If you can't, you don't understand it yet.
## Moving Forward
Avoiding these mistakes doesn't mean being paranoid about AI—it means being intentional. Vibe coding is powerful when you stay in the driver's seat: thinking critically, verifying outputs, and using AI to augment your skills rather than replace them.
The best vibe coders treat AI like a junior developer: productive and helpful, but requiring review and guidance. They know when to lean on it heavily and when to trust their own instincts. They use it to move faster without sacrificing code quality.
Start with awareness. As you code with AI this week, notice when you're falling into these patterns. Catch yourself accepting code blindly. Stop yourself from prompting for trivial changes. Question outputs that seem too perfect.
The developers who master vibe coding aren't the ones who generate the most code—they're the ones who generate the right code, understand it deeply, and ship with confidence.
Keep iterating, keep learning, and keep your critical thinking sharp. That's how you level up from novice to expert vibe coder.