managarten/picture/BUG_ANALYSIS.md
Till-JS c712a2504a feat: integrate uload and picture, unify package naming
- Add uload project with apps/web structure
  - Reorganize from flat to monorepo structure
  - Remove PocketBase binary and local data
  - Update to pnpm and @uload/web namespace

- Add picture project to monorepo
  - Remove embedded git repository

- Unify all package names to @{project}/{app} schema:
  - @maerchenzauber/* (was @storyteller/*)
  - @manacore/* (was manacore-*, manacore)
  - @manadeck/* (was web, backend, manadeck)
  - @memoro/* (was memoro-web, landing, memoro)
  - @picture/* (already unified)
  - @uload/web

- Add convenient dev scripts for all apps:
  - pnpm dev:{project}:web
  - pnpm dev:{project}:landing
  - pnpm dev:{project}:mobile
  - pnpm dev:{project}:backend

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-25 04:00:36 +01:00

5 KiB

🐛 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!

// 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

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

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

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

import { processGeneration } from '../process-generation/lib.ts';
// Now this works without conflict!

Step 4: Deploy

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:

    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:

    curl -X POST https://.../functions/v1/process-jobs \
      -H 'Authorization: Bearer SERVICE_ROLE_KEY'
    
  3. Test with real job:

    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