Troubleshooting Guide
Troubleshooting Guide
Section titled “Troubleshooting Guide”Solutions to common issues when developing and deploying ImageBot.
Installation Issues
Section titled “Installation Issues”Node Version Mismatch
Section titled “Node Version Mismatch”Error:
error imagebot@0.0.1: The engine "node" is incompatible with this module.Solution:
# Check Node versionnode --version
# Should be 18.x or higher# Install Node 18+ if needednvm install 18nvm use 18Wrangler Login Fails
Section titled “Wrangler Login Fails”Error:
Error: Failed to login. Please try again.Solution:
# Clear Wrangler cacherm -rf ~/.wrangler
# Try login againwrangler login
# If still fails, use API tokenwrangler login --api-key YOUR_API_KEYPackage Installation Errors
Section titled “Package Installation Errors”Error:
npm ERR! ERESOLVE unable to resolve dependency treeSolution:
# Clear npm cachenpm cache clean --force
# Delete node_modules and package-lock.jsonrm -rf node_modules package-lock.json
# Reinstall with legacy peer depsnpm install --legacy-peer-depsDatabase Issues
Section titled “Database Issues”Foreign Key Constraint Errors
Section titled “Foreign Key Constraint Errors”Error:
SQLITE_ERROR: no such column: team_id at offset 69Solution: Use the minimal schema versions that avoid foreign key constraints:
# Use teams-minimal.sql instead of teams-schema.sqlwrangler d1 execute imagebot-db --remote --file database/teams-minimal.sqlWhy: Cloudflare D1 has limitations with ALTER TABLE and complex foreign key constraints.
Database Not Found
Section titled “Database Not Found”Error:
Error: Database binding 'DB' not foundSolution:
- Verify database exists:
wrangler d1 list- Check
wrangler.tomlhas correct binding:
[[d1_databases]]binding = "DB"database_name = "imagebot-db"database_id = "your-database-id-here"- Ensure you’re running worker dev server:
npm run worker:devSchema Migration Fails
Section titled “Schema Migration Fails”Error:
Error: table 'users' already existsSolution:
Option 1: Use IF NOT EXISTS in schema (already included in schema-init.sql)
CREATE TABLE IF NOT EXISTS users (...)Option 2: Drop and recreate (⚠️ DELETES ALL DATA):
# Export data firstwrangler d1 export imagebot-db --output backup.sql
# Delete and recreate databasewrangler d1 delete imagebot-dbwrangler d1 create imagebot-db
# Apply schemawrangler d1 execute imagebot-db --remote --file database/schema-init.sqlWorker Issues
Section titled “Worker Issues”Worker Deployment Fails
Section titled “Worker Deployment Fails”Error:
Error: Script startup exceeded CPU time limitSolution:
- Remove unnecessary imports:
// Remove heavy libraries not used in production// Check worker/index.ts for large dependencies- Optimize initialization:
// Move heavy operations out of global scope// Lazy load modules only when needed- Check bundle size:
wrangler publish --dry-run --outdir=distls -lh distCORS Errors
Section titled “CORS Errors”Error (Browser Console):
Access to fetch at 'https://worker.dev/api/generate' from origin 'http://localhost:4321'has been blocked by CORS policySolution:
Update worker/index.ts CORS headers:
const corsHeaders = { 'Access-Control-Allow-Origin': '*', // Or specific origin 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization',};
// Handle OPTIONS preflightif (request.method === 'OPTIONS') { return new Response(null, { headers: corsHeaders });}
// Add to all responsesreturn new Response(JSON.stringify(data), { headers: { ...corsHeaders, 'Content-Type': 'application/json' }});401 Unauthorized Errors
Section titled “401 Unauthorized Errors”Error:
{"error": "Unauthorized"}Solution:
- Check JWT token is being sent:
// In browser consolelocalStorage.getItem('token')- Verify Authorization header:
fetch('https://worker.dev/api/images', { headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` }})- Check token hasn’t expired:
// Decode JWT (payload is middle part)const payload = JSON.parse(atob(token.split('.')[1]));console.log('Expires:', new Date(payload.exp * 1000));- Verify JWT_SECRET is set:
wrangler secret listWorker Not Updating
Section titled “Worker Not Updating”Error: Changes to worker code don’t appear after deployment.
Solution:
- Clear Cloudflare cache:
# Purge cache via APIcurl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/purge_cache" \ -H "Authorization: Bearer API_TOKEN" \ -d '{"purge_everything":true}'- Hard refresh browser:
- Chrome:
Cmd+Shift+R(Mac) orCtrl+Shift+R(Windows)
- Check deployment succeeded:
wrangler tail imagebot-worker# Trigger request and watch for logsFrontend Issues
Section titled “Frontend Issues”API_URL Not Defined
Section titled “API_URL Not Defined”Error:
TypeError: Cannot read property 'get' of undefinedSolution:
- Create
.envfile:
cp .env.example .env- Set API URL:
PUBLIC_API_URL=http://localhost:8787- Restart dev server:
npm run devImages Not Loading
Section titled “Images Not Loading”Error: Images show broken image icon or 404.
Solution:
- Check R2 bucket exists:
wrangler r2 bucket list- Verify R2 binding in
wrangler.toml:
[[r2_buckets]]binding = "IMAGES"bucket_name = "imagebot-images"- Configure R2 public access or custom domain:
# Option 1: Custom domainwrangler r2 bucket domain add imagebot-images --domain images.yourdomain.com
# Option 2: Public bucketwrangler r2 bucket cors put imagebot-images --allow-origin '*'- Update
r2_urlgeneration inworker/index.ts:
const r2Url = `https://images.yourdomain.com/${r2Key}`;// Or use R2 dev URL for testingconst r2Url = `https://imagebot-images.r2.dev/${r2Key}`;Tailwind Styles Not Applying
Section titled “Tailwind Styles Not Applying”Error: Components render but have no styling.
Solution:
- Verify Tailwind config includes all content paths:
export default { content: [ './src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}' ], // ...}- Import Tailwind in layout:
---import '../styles/global.css';---- Rebuild:
npm run buildAuthentication Issues
Section titled “Authentication Issues”Login Fails with Correct Password
Section titled “Login Fails with Correct Password”Error:
{"error": "Invalid credentials"}Solution:
- Check database has user:
wrangler d1 execute imagebot-db --remote --command \ "SELECT id, email FROM users WHERE email = 'user@example.com'"- Verify password was hashed during registration:
wrangler d1 execute imagebot-db --remote --command \ "SELECT password_hash FROM users WHERE email = 'user@example.com'"# Should be a long bcrypt hash starting with $2a$ or $2b$- Test bcrypt in isolation:
const bcrypt = require('bcryptjs');const hash = await bcrypt.hash('mypassword', 10);console.log(await bcrypt.compare('mypassword', hash)); // Should be trueSession Expires Too Quickly
Section titled “Session Expires Too Quickly”Error: Logged out after a few minutes.
Solution:
Update JWT expiration in worker/index.ts:
const token = await jwt.sign({ userId: user.id, exp: Math.floor(Date.now() / 1000) + (60 * 60 * 24 * 30) // 30 days instead of 7}, env.JWT_SECRET);Payment Issues
Section titled “Payment Issues”Stripe Webhook Fails
Section titled “Stripe Webhook Fails”Error:
{"error": "Invalid signature"}Solution:
- Verify webhook secret:
wrangler secret list# Should show STRIPE_WEBHOOK_SECRET- Test webhook signature:
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);const signature = request.headers.get('stripe-signature');const event = stripe.webhooks.constructEvent( rawBody, signature, process.env.STRIPE_WEBHOOK_SECRET);- Check Stripe Dashboard:
- Go to Developers → Webhooks
- Verify endpoint URL matches your Worker
- Check webhook logs for errors
Payment Intent Fails
Section titled “Payment Intent Fails”Error:
{"error": "Payment failed"}Solution:
- Use Stripe test cards:
- Success:
4242 4242 4242 4242 - Decline:
4000 0000 0000 0002 - Requires auth:
4000 0025 0000 3155
- Check Stripe logs:
stripe logs tail- Verify amount is in cents:
// Correctamount: 999, // $9.99
// Wrongamount: 9.99, // InvalidPerformance Issues
Section titled “Performance Issues”Slow Image Generation
Section titled “Slow Image Generation”Symptom: Images take 10+ seconds to generate.
Solution:
- Use faster models:
// Fast models'@cf/black-forest-labs/flux-1-schnell' // Fastest'@cf/stabilityai/stable-diffusion-xl-base-1.0' // Fast
// Slower models (higher quality)'@cf/runwayml/stable-diffusion-v1-5'- Reduce image size:
{ prompt: "...", model: "...", num_steps: 4, // Lower steps = faster (min 4 for Flux) guidance: 7.5 // Default}- Check AI model availability:
# Some models may have queue timescurl https://api.cloudflare.com/client/v4/accounts/ACCOUNT_ID/ai/models \ -H "Authorization: Bearer API_TOKEN"Gallery Loads Slowly
Section titled “Gallery Loads Slowly”Symptom: Gallery takes long time to load with many images.
Solution:
- Implement pagination (already in code):
// Frontend should paginateconst images = await api.get(`/api/images?limit=20&offset=${page * 20}`);-
Enable lazy loading (already in code via react-lazy-load-image-component)
-
Optimize R2 image delivery:
- Use Cloudflare Image Resizing
- Enable CDN caching
- Compress images before upload
Rate Limiting Issues
Section titled “Rate Limiting Issues”429 Too Many Requests
Section titled “429 Too Many Requests”Error:
{"error": "Rate limit exceeded. Try again in 60 seconds."}Solution:
- Implement exponential backoff:
async function retryWithBackoff(fn, maxRetries = 3) { for (let i = 0; i < maxRetries; i++) { try { return await fn(); } catch (error) { if (error.status === 429 && i < maxRetries - 1) { await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, i))); } else { throw error; } } }}- Check rate limit headers:
const response = await fetch('...');console.log('Rate limit:', response.headers.get('X-RateLimit-Remaining'));- Upgrade plan or request limit increase
Development Environment Issues
Section titled “Development Environment Issues”Port Already in Use
Section titled “Port Already in Use”Error:
Error: listen EADDRINUSE: address already in use :::4321Solution:
# Find process using portlsof -i :4321
# Kill processkill -9 PID
# Or use different portnpm run dev -- --port 3000Worker and Frontend Out of Sync
Section titled “Worker and Frontend Out of Sync”Symptom: Frontend calls API endpoint that doesn’t exist.
Solution:
- Ensure both are running:
# Terminal 1npm run dev
# Terminal 2npm run worker:dev- Check API URL matches:
# In .envPUBLIC_API_URL=http://localhost:8787
# Should match worker dev server port- Clear browser cache and reload
Production Issues
Section titled “Production Issues”500 Internal Server Error
Section titled “500 Internal Server Error”Error:
{"error": "Internal server error"}Solution:
- Check Worker logs:
wrangler tail imagebot-worker --status error- Review error details:
// Add better error logging in workertry { // ... code} catch (error) { console.error('Error details:', error); return new Response(JSON.stringify({ error: 'Internal server error', details: error.message // Only in development }), { status: 500 });}- Check Cloudflare dashboard:
- Workers → imagebot-worker → Metrics
- Look for error spikes and stack traces
Database Query Timeout
Section titled “Database Query Timeout”Error:
Error: Query exceeded time limitSolution:
- Add indexes:
CREATE INDEX idx_images_user_created ON images(user_id, created_at DESC);CREATE INDEX idx_collections_user ON collections(user_id);- Optimize query:
-- Bad: Full table scanSELECT * FROM images WHERE is_deleted = 0 ORDER BY created_at DESC;
-- Good: Uses indexSELECT * FROM images WHERE user_id = ? AND is_deleted = 0 ORDER BY created_at DESC LIMIT 20;- Use D1 analytics to find slow queries:
- Dashboard → D1 → imagebot-db → Analytics
Getting Help
Section titled “Getting Help”If you can’t resolve an issue:
-
Check logs:
Terminal window # Worker logswrangler tail imagebot-worker# Browser consoleOpen DevTools → Console -
Search GitHub issues:
-
Ask community:
- Discord: discord.gg/imagebot
- GitHub Discussions: github.com/your-org/imagebot/discussions
-
Contact support:
- Email: support@imagebot.com
- Include: Error message, logs, steps to reproduce
Debugging Tips
Section titled “Debugging Tips”Enable Verbose Logging
Section titled “Enable Verbose Logging”const DEBUG = true;
function log(...args: any[]) { if (DEBUG) { console.log('[ImageBot]', ...args); }}
// Use throughout codelog('Generating image for user:', userId);log('Prompt:', prompt);Test API with cURL
Section titled “Test API with cURL”# Test health endpointcurl https://imagebot-worker.workers.dev/api/health
# Test authenticated endpointcurl https://imagebot-worker.workers.dev/api/images \ -H "Authorization: Bearer YOUR_TOKEN"
# Test POST requestcurl -X POST https://imagebot-worker.workers.dev/api/generate \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"prompt":"test","model":"@cf/black-forest-labs/flux-1-schnell"}'Browser DevTools Network Tab
Section titled “Browser DevTools Network Tab”- Open DevTools → Network
- Filter by “Fetch/XHR”
- Click request to see:
- Headers (including Authorization)
- Payload
- Response
- Timing
Database Inspection
Section titled “Database Inspection”# List all tableswrangler d1 execute imagebot-db --remote --command \ "SELECT name FROM sqlite_master WHERE type='table'"
# Check table schemawrangler d1 execute imagebot-db --remote --command \ "PRAGMA table_info(users)"
# Sample datawrangler d1 execute imagebot-db --remote --command \ "SELECT * FROM images LIMIT 5"