Skip to main content

The Trap

Traceo’s repository factory (traceo_mcp_server/repositories/factory.py) selects the storage backend based on two conditions: (1) DATABASE_URL is set, and (2) psycopg3 is importable. If either condition fails, it silently falls back to file-based storage with only a warning log. This means:
  • Running python scripts/seed_requirements.py locally without psycopg3 installed creates 80 YAML files on disk
  • The script reports “Seeded 80 requirements” with zero errors
  • The Railway Postgres database remains completely empty
  • The dashboard shows all zeros
The fallback is intentional (graceful degradation for local dev), but it creates a dangerous false-positive during seeding operations.

The Fix

For seeding scripts that target production: bypass the factory entirely and connect to Postgres directly via psycopg3. The convert_and_seed.py script does this correctly — it opens its own AsyncConnectionPool with an explicit --database-url parameter instead of going through RequirementService. The key lesson: seeding scripts should never rely on the application’s storage abstraction layer when targeting a specific backend.

Pattern Recognition

This is an instance of the “transparent proxy” anti-pattern in multi-backend systems. When a factory transparently swaps backends, operations that depend on a specific backend can silently succeed against the wrong one. The mitigation is: seed scripts should always connect directly to the target database, not through the application’s repository abstraction.