THIS POST WAS GENERATED BY AI
# Windows Environment Setup & Troubleshooting
This document covers Windows-specific configuration and common issues when developing ClientBridge Laravel on Windows with Laravel Herd and Git Bash.
## Table of Contents
– [Laravel Herd Configuration](#laravel-herd-configuration)
– [Git Bash Compatibility](#git-bash-compatibility)
– [Common Issues](#common-issues)
– [Environment Setup](#environment-setup)
## Laravel Herd Configuration
### Overview
Laravel Herd is a native Windows application that provides PHP, Composer, and related tools. It installs in the user’s home directory under `.config/herd/`.
**Installation Location:**
“`
C:\Users\<username>\.config\herd\
“`
**Key Directories:**
– **PHP Binaries:** `~/.config/herd/bin/php84/` (version number may vary)
– **Herd Executables:** `~/.config/herd/bin/`
– **Composer:** `~/.config/herd/bin/composer.bat`
### Included Tools
Herd provides the following tools as Windows batch files (`.bat`):
– `php.bat` – PHP CLI
– `composer.bat` – Composer dependency manager
– `laravel.bat` – Laravel installer
– `herd.bat` – Herd management CLI
## Git Bash Compatibility
### The Problem
Git Bash on Windows cannot execute `.bat` (batch) files directly through standard shell aliases. This causes issues when trying to use Herd-provided tools like Composer.
**Symptom:**
“`bash
$ composer –version
bash: composer: command not found
“`
### The Solution
Create a `~/.bashrc` file with bash functions that wrap the batch files using `cmd //c`:
**File Location:** `C:\Users\<username>\.bashrc`
**Contents:**
“`bash
# Laravel Herd Aliases – please do not remove these lines
alias php=”php.bat”
alias herd=”herd.bat”
alias laravel=”laravel.bat”
# Composer function for Git Bash compatibility
composer() {
cmd //c “C:\Users\alexr\.config\herd\bin\composer.bat $*”
}
export -f composer
“`
**Why This Works:**
1. Simple aliases work for PHP, Herd, and Laravel because they’re in the system PATH
2. Composer requires a function because we need to pass arguments (`$*`) to the batch file
3. `cmd //c` executes a Windows command and returns to bash
4. The double slash `//` prevents Git Bash from converting to a Unix path
5. `export -f composer` makes the function available to subshells
### Making It Permanent
To load `.bashrc` automatically on every Git Bash session, create a `~/.bash_profile`:
**File Location:** `C:\Users\<username>\.bash_profile`
**Contents:**
“`bash
# Load .bashrc if it exists
if [ -f ~/.bashrc ]; then
source ~/.bashrc
fi
“`
### Manual Loading
If you don’t want to create `.bash_profile`, you can manually load the configuration in each session:
“`bash
source ~/.bashrc
“`
## Common Issues
### Issue: “Target class [auth] does not exist” After Git Pull
**Symptom:** Running `php artisan` commands fails with “Target class [auth] does not exist”
**Root Cause:** The `bootstrap/app.php` file contains an unguarded call to `auth()` in the exceptions context that executes before Laravel’s authentication system is fully bootstrapped during CLI commands. This often occurs after git pulls when changes revert previous fixes.
**Solution:** Guard the `auth()` call in `bootstrap/app.php`
“`php
// ❌ PROBLEMATIC CODE (causes CLI failures)
$exceptions->context(fn () => [
‘user_id’ => auth()->id() ?? null,
‘env’ => app()->environment(),
]);
// ✅ FIXED CODE (safe for CLI)
$exceptions->context(fn () => [
‘user_id’ => (function () {
try {
return function_exists(‘auth’) && app()->bound(‘auth’) ? auth()->id() : null;
} catch (\Throwable $e) {
return null;
}
})(),
‘env’ => app()->environment(),
]);
“`
**Prevention:** Always guard early auth calls in bootstrap files with existence checks and try/catch blocks.
### Issue: “Class ‘Laravel\Boost\BoostServiceProvider’ not found”
**Symptom:** Artisan commands fail with provider class not found errors after git pull or dependency changes.
**Root Cause:** Composer autoload mappings are stale, or Laravel’s package discovery cache is outdated.
**Solution Steps:**
1. **Create Required Directories** (if missing):
“`bash
mkdir -p storage/framework/views storage/logs bootstrap/cache
“`
2. **Regenerate Autoload Files**:
“`bash
composer dump-autoload –optimize –no-scripts
“`
3. **Clear Laravel Caches**:
“`bash
php artisan optimize:clear
“`
4. **Regenerate Package Discovery**:
“`bash
php artisan package:discover –ansi
“`
5. **Verify Provider Discovery**:
“`bash
php artisan tinker –execute=”var_export(class_exists(‘Laravel\\Boost\\BoostServiceProvider’));”
“`
### Issue: Composer Script Failures During Install
**Symptom:** `composer install` or `composer dump-autoload` fails with “pre-autoload-dump event returned with error code 1”
**Root Cause:** Composer scripts try to create directories that don’t exist or have permission issues during the pre-autoload-dump phase.
**Solution:**
“`bash
# Create directories manually first (prevents script failure)
mkdir -p storage/framework/views storage/framework/cache storage/framework/sessions storage/logs bootstrap/cache
# Then run composer install normally (script will now succeed)
composer.bat install –optimize-autoloader
# Alternative if still failing – bypass scripts entirely:
composer dump-autoload –optimize –no-scripts
php artisan optimize:clear && php artisan package:discover
“`
### Issue: MissingAppKeyException After Environment Changes
**Symptom:** `MissingAppKeyException` errors in tests or application
**Root Cause:** The `APP_KEY` in `.env` is missing or invalid after environment changes or fresh pulls.
**Solution:**
“`bash
php artisan key:generate
“`
**Verification:**
“`bash
php artisan config:show app.key
# Should show: app.key …. base64:FBmJhkH6BD0AZ2UWtRosyN4Eaa372d2yuBUP79At1VU=
“`
### Issue: Login Redirects to Wrong URLs (e.g., /admin/leads/partial)
**Symptom:** After login, users are redirected to AJAX endpoints or partial views instead of proper dashboards.
**Root Cause:** Laravel’s `redirect()->intended()` method stores the last attempted URL in the session. If users previously accessed partial views or AJAX endpoints, the login redirect uses those URLs.
**Solution:** Clear intended URLs in the AuthenticatedSessionController:
“`php
public function store(LoginRequest $request): RedirectResponse
{
$request->authenticate();
$request->session()->regenerate();
// Clear any intended URL to prevent unwanted redirects
$request->session()->forget(‘url.intended’);
// Force direct redirect based on user role
$user = auth()->user();
if ($user->role === ‘company_administrator’) {
return redirect()->route(‘admin.dashboard’);
} else {
return redirect()->route(‘dashboard’);
}
}
“`
**Session Debugging:**
“`bash
# Clear all sessions to eliminate stored URLs
php artisan tinker –execute=”DB::table(‘sessions’)->truncate();”
# Check session count
php artisan tinker –execute=”echo ‘Session count: ‘ . DB::table(‘sessions’)->count();”
“`
### Issue: PSR-4 Autoloading Standard Violations
**Symptom:** “Class [Name] does not comply with psr-4 autoloading standard” during composer operations.
**Example Fix:**
“`php
// ❌ Missing namespace declaration
<?php
use Tests\TestCase;
class EmailDeliverabilityTest extends TestCase
// ✅ Proper namespace declaration
<?php
namespace Tests\Feature;
use Tests\TestCase;
class EmailDeliverabilityTest extends TestCase
“`
### Issue: “composer: command not found”
**Cause:** Git Bash cannot execute `.bat` files directly through aliases.
**Solution:** Use the bash function approach documented above.
**Verification:**
“`bash
$ composer –version
Composer version 2.8.8 2025-04-04 16:56:46
PHP version 8.4.7 (C:\Users\alexr\.config\herd\bin\php84\php.exe)
“`
### Issue: “php: command not found”
**Cause:** Herd’s PHP bin directory is not in your PATH.
**Solution:**
1. Check if Herd is running (system tray icon)
2. Restart Herd application
3. Close and reopen Git Bash
4. Verify PATH includes: `~/.config/herd/bin/php84/`
**Check PATH:**
“`bash
echo $PATH | grep -o “.config/herd/bin/php84”
“`
### Issue: Laravel commands fail with “Class not found”
**Cause:** Autoloader is out of sync or dependencies are missing.
**Solution:**
“`bash
composer install
composer dump-autoload
php artisan config:clear
php artisan cache:clear
“`
### Issue: CRLF vs LF line endings
**Symptom:** Git warnings about CRLF/LF conversions, scripts fail to execute.
**Solution:** Configure Git to handle line endings properly:
“`bash
# For this repository only
git config core.autocrlf true
# Globally for all repositories
git config –global core.autocrlf true
“`
**Alternative:** Use `.gitattributes` file (already in project):
“`
* text=auto eol=lf
*.bat text eol=crlf
“`
### Issue: Permissions errors on storage/logs
**Cause:** Windows file permissions differ from Unix.
**Solution:**
“`bash
# These commands work in Git Bash
chmod -R 775 storage
chmod -R 775 bootstrap/cache
# Or use PHP to set permissions
php artisan storage:link
“`
### Issue: Symlinks not working
**Cause:** Windows requires administrator privileges to create symlinks.
**Solution:**
1. Run Git Bash as Administrator
2. Or enable Developer Mode in Windows Settings
3. Then run: `php artisan storage:link`
## Environment Setup
### Required Environment Variables
The following are set automatically by Herd but can be verified:
“`bash
# Check PHP version
php –version
# Check Composer version
composer –version
# Check Laravel installer
laravel –version
# Verify PATH includes Herd
echo $PATH | grep herd
“`
### Recommended Git Bash Configuration
**`~/.bashrc`:**
“`bash
# Laravel Herd Aliases
alias php=”php.bat”
alias herd=”herd.bat”
alias laravel=”laravel.bat”
# Composer function for Git Bash compatibility
composer() {
cmd //c “C:\Users\alexr\.config\herd\bin\composer.bat $*”
}
export -f composer
# Laravel Artisan alias
alias artisan=”php artisan”
# Common shortcuts
alias tinker=”php artisan tinker”
alias migrate=”php artisan migrate”
alias fresh=”php artisan migrate:fresh –seed”
# Git shortcuts
alias gs=”git status”
alias gp=”git push”
alias gl=”git log –oneline -10″
“`
### VSCode Integration
If using VSCode with Git Bash as the integrated terminal:
**settings.json:**
“`json
{
“terminal.integrated.defaultProfile.windows”: “Git Bash”,
“terminal.integrated.profiles.windows”: {
“Git Bash”: {
“path”: “C:\\Program Files\\Git\\bin\\bash.exe”,
“args”: [“-l”]
}
}
}
“`
The `-l` flag ensures it loads as a login shell, which sources `~/.bash_profile` and `~/.bashrc`.
## Development Workflow
### Starting Development
1. **Ensure Herd is running** (check system tray)
2. **Open Git Bash** in project directory
3. **Load environment** (if not auto-loaded):
“`bash
source ~/.bashrc
“`
4. **Verify tools are available:**
“`bash
php –version
composer –version
“`
5. **Start development:**
“`bash
php artisan serve
# Or use Herd’s built-in server (automatic)
“`
### Deployment to VPS (Ubuntu/Linux)
When deploying from Windows to Linux VPS, be aware of:
1. **Line endings:** Ensure `.gitattributes` is properly configured
2. **Path differences:** Windows uses backslashes, Linux uses forward slashes
3. **Case sensitivity:** Linux filesystems are case-sensitive
4. **Permissions:** Linux requires specific file permissions (775 for storage, 644 for files)
5. **Batch files:** `.bat` files won’t work on Linux (use bash scripts instead)
### Testing
“`bash
# Run tests
php artisan test
# Or with Pest
./vendor/bin/pest
# Run specific test
php artisan test –filter=BookingTest
“`
## Quick Recovery Checklist After Git Pull
When encountering issues after `git pull` or major environment changes, follow this systematic approach:
### 1. Verify Environment Basics
“`bash
# Check PHP availability
php -v
# Check Composer availability
composer -V
# Verify you’re in the project root
pwd
# Should show: /c/Users/[username]/Documents/GitHub/clientbridge-laravel
“`
### 2. Fix Bootstrap Authentication Issues
“`bash
# Test basic artisan functionality
php artisan –version
# If you get “Target class [auth] does not exist”:
# Check bootstrap/app.php for unguarded auth() calls in exceptions context
# Apply the guarded auth solution documented above
“`
### 3. Regenerate Dependencies & Caches
“`bash
# Create required directories (if missing)
mkdir -p storage/framework/views storage/logs bootstrap/cache
# Regenerate autoload (bypass scripts if they fail)
composer dump-autoload –optimize –no-scripts
# Clear and regenerate ALL Laravel caches
php artisan optimize:clear
# Regenerate package discovery cache
php artisan package:discover –ansi
“`
### 4. Handle Database & Application Keys
“`bash
# Generate app key if missing (prevents MissingAppKeyException)
php artisan key:generate
# Run any pending migrations
php artisan migrate
# Clear sessions if experiencing login redirect issues
php artisan tinker –execute=”DB::table(‘sessions’)->truncate();”
“`
### 5. Build Frontend Assets
“`bash
# Install/update NPM dependencies
npm install
# Build production assets
npm run build
“`
### 6. Reinstall Development Tools
“`bash
# Reinstall Laravel Boost MCP server for VS Code integration
php artisan boost:install
“`
### 7. Final Verification Tests
“`bash
# Test artisan commands work
php artisan route:list | head -5
# Test class autoloading
php artisan tinker –execute=”var_export(class_exists(‘Laravel\\Boost\\BoostServiceProvider’));”
# Test application key
php artisan config:show app.key
# Test basic authentication (if logged in)
php artisan tinker –execute=”echo auth()->check() ? ‘Auth working’ : ‘Auth ready’;”
“`
## Standard Troubleshooting Checklist
For general development issues:
– [ ] Is Herd running? (Check system tray)
– [ ] Did you source `~/.bashrc`? Run: `source ~/.bashrc`
– [ ] Is PHP in PATH? Run: `which php.bat`
– [ ] Is Composer working? Run: `composer –version`
– [ ] Are dependencies installed? Run: `composer install`
– [ ] Is `.env` file present? Run: `ls -la .env`
– [ ] Are permissions correct? Run: `ls -la storage/`
– [ ] Bootstrap issues? Check: `bootstrap/app.php` for unguarded auth calls
– [ ] Clear caches: `php artisan optimize:clear`
– [ ] Regenerate discovery: `php artisan package:discover`
– [ ] Restart Herd application
– [ ] Close and reopen Git Bash
## Emergency Recovery Commands
**Full environment reset after major issues:**
“`bash
# Complete recovery sequence (run in project root)
mkdir -p storage/framework/views storage/logs bootstrap/cache
composer dump-autoload –optimize –no-scripts
php artisan optimize:clear
php artisan package:discover –ansi
php artisan key:generate
php artisan migrate
npm install && npm run build
php artisan boost:install
“`
**Debug specific issues:**
“`bash
# Check authentication system
php artisan tinker –execute=”var_export([
‘auth_function_exists’ => function_exists(‘auth’),
‘auth_bound’ => app()->bound(‘auth’),
‘user_model_exists’ => class_exists(‘App\\Models\\User’)
]);”
# Verify critical service providers are discovered
php artisan tinker –execute=”var_export([
‘boost_provider’ => class_exists(‘Laravel\\Boost\\BoostServiceProvider’),
‘mcp_provider’ => class_exists(‘Laravel\\Mcp\\Server\\McpServiceProvider’),
‘breeze_provider’ => class_exists(‘Laravel\\Breeze\\BreezeServiceProvider’)
]);”
# Clear all caches and sessions completely
php artisan optimize:clear && php artisan tinker –execute=”
DB::table(‘sessions’)->truncate();
echo ‘All caches and sessions cleared.’;
“
“`
## Additional Resources
– **Laravel Herd Documentation:** https://herd.laravel.com/
– **Git Bash Documentation:** https://git-scm.com/docs
– **Laravel Documentation:** https://laravel.com/docs
– **Composer Documentation:** https://getcomposer.org/doc/
## Maintenance
### Updating Herd
Herd auto-updates, but you can manually check:
1. Click Herd icon in system tray
2. Select “Check for Updates”
3. Restart Herd after update
4. Verify PHP/Composer versions: `php –version && composer –version`
### Updating Composer
“`bash
composer self-update
“`
### Changing PHP Version
Herd supports multiple PHP versions:
1. Right-click Herd icon in system tray
2. Select PHP version (8.1, 8.2, 8.3, 8.4)
3. Update `.bashrc` path if needed: `~/.config/herd/bin/php84/` → `php83/` etc.
## Prevention Best Practices
### Before Git Pull
– [ ] Commit or stash local changes
– [ ] Note any custom environment configurations
– [ ] Backup `.env` file if it contains unique local settings
### After Git Pull
– [ ] Run the Quick Recovery Checklist above
– [ ] Check `bootstrap/app.php` for reverted auth guards
– [ ] Verify critical routes still work: `php artisan route:list | grep dashboard`
– [ ] Test login functionality to ensure proper redirects
### Code Practices
1. **Always guard early auth calls** in bootstrap contexts:
“`php
// Safe pattern for bootstrap files
‘user_id’ => (function () {
try {
return function_exists(‘auth’) && app()->bound(‘auth’) ? auth()->id() : null;
} catch (\Throwable $e) {
return null;
}
})(),
“`
2. **Clear intended URLs** in login controllers:
“`php
// Prevent unwanted redirects after authentication
$request->session()->forget(‘url.intended’);
“`
3. **Use proper namespaces** in test files:
“`php
<?php
namespace Tests\Feature; // Always include namespace
“`
4. **Regenerate caches** after dependency changes:
“`bash
composer dump-autoload –optimize
php artisan optimize:clear
php artisan package:discover
“`
## Script Automation
### Setup Script for New Windows Environments
Create `scripts/setup-herd-gitbash.sh` (already exists in project):
“`bash
#!/bin/bash
# Sets up Git Bash to work with Laravel Herd on Windows
BASHRC=”$HOME/.bashrc”
HERD_BIN=”$HOME/.config/herd/bin”
# Add PATH export for Herd binaries
if ! grep -q “export PATH.*herd/bin” “$BASHRC” 2>/dev/null; then
echo “” >> “$BASHRC”
echo “# Laravel Herd PATH” >> “$BASHRC”
echo “export PATH=\”\$HOME/.config/herd/bin:\$PATH\”” >> “$BASHRC”
echo “Added Herd bin to PATH”
else
echo “Herd PATH already configured”
fi
# Add aliases for .bat files
ALIASES=(
“alias php=’php.bat’”
“alias composer=’composer.bat’”
“alias herd=’herd.bat’”
“alias laravel=’laravel.bat’”
)
for alias_cmd in “${ALIASES[@]}”; do
if ! grep -Fq “$alias_cmd” “$BASHRC” 2>/dev/null; then
echo “$alias_cmd” >> “$BASHRC”
echo “Added: $alias_cmd”
else
echo “Alias already exists: $alias_cmd”
fi
done
echo “Setup complete! Run ‘source ~/.bashrc’ to apply changes.”
“`
### Post-Pull Recovery Script
Consider creating `scripts/post-pull-recovery.sh`:
“`bash
#!/bin/bash
# Automated recovery after git pull
echo “🔧 Starting post-pull recovery…”
# Step 1: Create required directories
echo “📁 Creating required directories…”
mkdir -p storage/framework/views storage/logs bootstrap/cache
# Step 2: Fix autoload issues
echo “🔄 Regenerating autoload…”
composer dump-autoload –optimize –no-scripts
# Step 3: Clear Laravel caches
echo “🧹 Clearing Laravel caches…”
php artisan optimize:clear
# Step 4: Regenerate package discovery
echo “📦 Regenerating package discovery…”
php artisan package:discover –ansi
# Step 5: Generate app key if missing
echo “🔑 Checking application key…”
if ! php artisan config:show app.key | grep -q “base64:”; then
echo “Generating new application key…”
php artisan key:generate
fi
# Step 6: Run migrations
echo “📊 Running migrations…”
php artisan migrate –force
# Step 7: Clear sessions
echo “🧼 Clearing sessions…”
php artisan tinker –execute=”DB::table(‘sessions’)->truncate(); echo ‘Sessions cleared’;”
# Step 8: Build frontend
echo “🎨 Building frontend assets…”
npm install
npm run build
echo “echo “✅ Recovery complete! Environment should now be ready.”
“`
—
## Windows-Specific Directory Permission Issues
### Issue: “bootstrap\cache directory must be present and writable”
**Symptom:** Laravel fails with error: “The bootstrap\cache directory must be present and writable.”
**Root Cause:** Windows file system permissions or read-only attributes prevent Laravel from writing to the bootstrap/cache directory.
**Solutions (in order of preference):**
**Solution 1 – Remove Read-Only Attribute (RECOMMENDED):**
“`powershell
# In PowerShell (no admin required)
attrib -r +a .\bootstrap\cache
“`
**Solution 2 – Create Directory with Proper Attributes:**
“`powershell
# In PowerShell
New-Item -Path “bootstrap\cache” -ItemType Directory -Force
attrib -r +a .\bootstrap\cache
“`
**Solution 3 – Grant Full Permissions:**
“`powershell
# In PowerShell as Administrator
icacls “bootstrap\cache” /grant Everyone:F /T
“`
**Solution 4 – Use the Fix Script:**
“`bash
# In Git Bash
bash scripts/fix-bootstrap-cache.sh
“`
**Verification:**
“`bash
# Test write permissions
touch bootstrap/cache/test.tmp
rm bootstrap/cache/test.tmp
“`
**Notes:**
– The `attrib` command removes the read-only flag (`-r`) and sets the archive attribute (`+a`)
– This is often needed after cloning a repository on Windows
– The issue can also occur after extracting a ZIP archive
– Antivirus software may sometimes interfere with directory creation