managarten/apps/picture/BUG_ANALYSIS.md
Wuesteon d36b321d9d style: auto-format codebase with Prettier
Applied formatting to 1487+ files using pnpm format:write
  - TypeScript/JavaScript files
  - Svelte components
  - Astro pages
  - JSON configs
  - Markdown docs

  13 files still need manual review (Astro JSX comments)
2025-11-27 18:33:16 +01:00

216 lines
5.1 KiB
Markdown

# 🐛 Bug Analysis: process-jobs Function
**Date:** 2025-10-09
**Status:****ROOT CAUSE IDENTIFIED**
---
## Problem
The `process-jobs` Edge Function fails with error:
```
{"success":false,"error":"Cannot read properties of undefined (reading 'substring')"}
```
## Investigation Steps
### Step 1: Test without imports
Created `process-jobs-test` with minimal code (no imports).
**Result:** ✅ Works perfectly
- Environment variables present
- Supabase client initializes
- `claim_next_job()` RPC works
### Step 2: Test WITH process-generation import
Added `import { processGeneration } from '../process-generation/index.ts';`
**Result:** ❌ Same error returns
## Root Cause
**The `process-generation/index.ts` file has a `Deno.serve()` handler at the end!**
```typescript
// Line 522-565 of process-generation/index.ts
Deno.serve(async (req: Request) => {
// Handler code...
});
```
**Why this causes the error:**
1. Edge Functions can only have ONE `Deno.serve()` call
2. When `process-jobs` imports `process-generation/index.ts`, it executes the file
3. This tries to call `Deno.serve()` a second time
4. This causes a runtime error in Deno/Edge Functions environment
5. The error happens during import, before any of our code runs
## Solution
### Option A: Extract to Shared Module (RECOMMENDED)
Create a new file `process-generation/lib.ts` that contains ONLY the `processGeneration()` function and helper functions (NO Deno.serve).
**Structure:**
```
supabase/functions/
├── process-generation/
│ ├── lib.ts ← Pure functions, NO Deno.serve
│ └── index.ts ← Edge Function handler, imports from lib.ts
├── process-jobs/
│ └── index.ts ← Imports from ../process-generation/lib.ts
```
**Benefits:**
- Clean separation
- Reusable code
- Each function has its own Deno.serve
### Option B: Inline Code (FALLBACK)
Copy-paste the `processGeneration()` function directly into `process-jobs/index.ts`.
**Benefits:**
- Simple
- No import issues
- All code in one place
**Drawbacks:**
- Code duplication
- Harder to maintain
- Larger file
### Option C: Remove Deno.serve from process-generation
Remove the Deno.serve handler from `process-generation/index.ts` entirely if it's not needed as a standalone function.
**Drawbacks:**
- Can't call process-generation directly for testing
- Loses standalone functionality
---
## Recommended Implementation
**Go with Option A: Extract to Shared Module**
### Step 1: Create `process-generation/lib.ts`
Extract these from `index.ts`:
- All interfaces (ModelConfig, GenerationParams, GenerationResult)
- All helper functions (gcd, simplifyAspectRatio, convertImageToBase64, buildModelInput, determineOutputFormat)
- Main function: `processGeneration()`
### Step 2: Update `process-generation/index.ts`
```typescript
import 'jsr:@supabase/functions-js/edge-runtime.d.ts';
import { processGeneration } from './lib.ts';
Deno.serve(async (req: Request) => {
// Handler code...
const result = await processGeneration(params, replicateApiToken);
// Return response...
});
```
### Step 3: Update `process-jobs/index.ts`
```typescript
import { processGeneration } from '../process-generation/lib.ts';
// Now this works without conflict!
```
### Step 4: Deploy
```bash
npx supabase functions deploy process-generation --project-ref mjuvnnjxwfwlmxjsgkqu
npx supabase functions deploy process-jobs --project-ref mjuvnnjxwfwlmxjsgkqu
```
---
## Testing Plan
1. **Test process-generation standalone:**
```bash
curl -X POST https://.../ /functions/v1/process-generation \
-H 'Authorization: Bearer SERVICE_ROLE_KEY' \
-d '{"prompt": "test", "model_id": "flux-schnell", ...}'
```
2. **Test process-jobs:**
```bash
curl -X POST https://.../functions/v1/process-jobs \
-H 'Authorization: Bearer SERVICE_ROLE_KEY'
```
3. **Test with real job:**
```sql
SELECT enqueue_job(
'generate-image',
'{"generation_id": "test-id", "prompt": "test", ...}'::jsonb,
0
);
```
Then trigger process-jobs and verify job is processed.
---
## Timeline
- **14:00 UTC** - Bug discovered during deployment
- **14:15 UTC** - Initial debugging started
- **14:30 UTC** - Created minimal test function (works)
- **14:35 UTC** - Added import (fails - reproduced bug)
- **14:40 UTC** - **ROOT CAUSE IDENTIFIED: Deno.serve() conflict**
- **14:45 UTC** - Solution designed
- **Next:** Implement fix
---
## Lessons Learned
1. **Edge Functions can only have ONE Deno.serve() per file**
2. **When importing files, ALL code in that file executes (including Deno.serve)**
3. **Shared code should be in separate files without Deno.serve()**
4. **Always test imports early to catch these issues**
---
## Impact
**Before Fix:**
- ❌ process-jobs fails immediately
- ❌ Cron job fails every minute
- ❌ Jobs stay pending forever
- ✅ Other functions work fine
**After Fix:**
- ✅ process-jobs works
- ✅ Cron job processes queue
- ✅ End-to-end flow complete
- ✅ System fully operational
---
**Fixed By:** Claude Code
**Status:** Ready to implement
**ETA:** 15 minutes