# Troubleshooting Guide

> Common errors and how to fix them

---

## TanStack Query Errors

### "No QueryClient set"

**Error:**
```
Error: No QueryClient set, use QueryClientProvider to set one
```

**Causa:** QueryProvider no está envolviendo la app.

**Solución:**
```tsx
// App.tsx
import { QueryProvider } from './providers/QueryProvider';

function App() {
  return (
    <QueryProvider>
      <DContextProvider>
        {/* content */}
      </DContextProvider>
    </QueryProvider>
  );
}
```

---

### "Invalid hook call" con useQuery

**Error:**
```
Invalid hook call. Hooks can only be called inside of the body of a function component.
```

**Causa:** Llamando useQuery fuera de componente o en función regular.

**Solución:** Asegura que el hook se llama dentro de un componente:

```typescript
// ❌ MAL - Fuera de componente
const data = useAccounts(); // Error

// ✅ BIEN - Dentro de componente
function MyComponent() {
  const { data } = useAccounts();
  return <div>{data}</div>;
}
```

---

### Query no se ejecuta (enabled)

**Síntoma:** useQuery nunca hace fetch.

**Causa:** `enabled: false` o condición no cumplida.

**Solución:**
```typescript
// Verificar que la condición de enabled sea correcta
const { data } = useQuery({
  queryKey: ['account', id],
  queryFn: () => getAccount(id),
  enabled: !!id,  // ← Verifica que id no sea null/undefined
});

// Debug: log para verificar
console.log('Query enabled:', !!id, 'id:', id);
```

---

### Cache desactualizado después de mutation

**Síntoma:** Datos no se actualizan después de crear/editar.

**Causa:** Falta invalidar queries.

**Solución:**
```typescript
const mutation = useMutation({
  mutationFn: createAccount,
  onSuccess: () => {
    // Invalidar para refetch
    queryClient.invalidateQueries({ queryKey: ['accounts'] });
  },
});
```

---

## Zustand Errors

### Store undefined en primer render

**Síntoma:** `Cannot read property 'X' of undefined`

**Causa:** Selector retorna undefined antes de inicializar.

**Solución:** Proveer valor por defecto:
```typescript
// ❌ MAL
const items = useUIStore(state => state.items);

// ✅ BIEN - Con fallback
const items = useUIStore(state => state.items) ?? [];
```

---

### Cambios de estado no causan re-render

**Síntoma:** UI no actualiza cuando cambia estado.

**Causa:** Mutación directa del estado.

**Solución:** Siempre usar `set` con nuevo objeto:
```typescript
// ❌ MAL - Mutación directa
set((state) => {
  state.items.push(newItem);  // Mutando directamente
  return state;
});

// ✅ BIEN - Nuevo objeto
set((state) => ({
  items: [...state.items, newItem]
}));
```

---

### DevTools no muestra acciones

**Síntoma:** Redux DevTools vacío.

**Causa:** Falta middleware devtools o action name.

**Solución:**
```typescript
export const useUIStore = create<UIState>()(
  devtools(  // ← Middleware
    (set) => ({
      setSelected: (id) => set(
        { selectedId: id },
        false,
        'ui/setSelected'  // ← Action name
      ),
    }),
    { name: 'ui-store' }  // ← Store name
  )
);
```

---

## 🚨 Icons Show as "?" (Most Common Error)

**Symptom:** All icons display as "?" instead of the icon graphic.

**Cause:** Using Bootstrap Icons (kebab-case) instead of Lucide Icons (PascalCase).

**Solution:**

1. Find all icon usages:
   ```bash
   grep -rn 'icon\(Start\|End\)\?=' src/
   ```

2. Convert to PascalCase using table in `modyo://docs/widgets/components-icons`:
   ```tsx
   // ❌ WRONG
   <DIcon icon="credit-card" />

   // ✅ CORRECT
   <DIcon icon="CreditCard" />
   ```

3. Verify fix:
   ```bash
   # Should return 0 matches
   grep -rn 'icon\(Start\|End\)\?=["'"'"'][a-z]\+-[a-z]\+' src/
   ```

**Time to fix:** 1-2 minutes per icon (or 30+ minutes if you have 40+ icons).

**Prevention:** Read `docs/INDEX.md` BEFORE generating code.

---

## Common Build Errors

### TypeScript: Module not found

**Error:**
```
Cannot find module '../services/repositories/accountsRepository'
```

**Causa:** Path incorrecto o archivo no existe.

**Solución:**
1. Verificar que el archivo existe
2. Verificar el path relativo
3. Verificar que exporta lo que importas

---

### TypeScript: Type errors con useQuery

**Error:**
```
Type 'undefined' is not assignable to type 'Account[]'
```

**Causa:** `data` de useQuery puede ser `undefined` mientras carga.

**Solución:**
```typescript
// ❌ MAL
const { data } = useAccounts();
return data.map(...);  // Error si data es undefined

// ✅ BIEN - Optional chaining
const { data } = useAccounts();
return data?.map(...) ?? [];

// ✅ BIEN - Guard clause
const { data, isLoading } = useAccounts();
if (isLoading || !data) return <Loading />;
return data.map(...);
```

---

## Runtime Errors

### Modal Not Found

**Symptom:** Error "Portal 'modalName' not found" when trying to open a modal.

**Cause:** Modal not registered in `DContextProvider.availablePortals`.

**Solution:** Register the modal in `src/main.tsx`:
```tsx
<DContextProvider
  availablePortals={{
    'modalName': ModalComponent,
  }}
>
  <App />
</DContextProvider>
```

---

### Fetch sin AbortController

**Síntoma:** Warnings de "Can't perform a React state update on an unmounted component"

**Causa:** Repository no cancela requests cuando componente se desmonta.

**Solución:** El nuevo stack con TanStack Query maneja esto automáticamente:
```typescript
// TanStack Query cancela requests automáticamente
export function useAccounts() {
  return useQuery({
    queryKey: ['accounts'],
    queryFn: ({ signal }) => getAccounts(signal),  // signal se pasa automáticamente
  });
}
```

---

**Last Updated:** December 2025
