Most Signia deployment problems fall into a small number of categories: a missing or untrained ML model, an environment variable that was left unset, a misconfigured static file backend, or a misunderstanding about how Railway’s ephemeral filesystem interacts with the application. The expandable sections below document each known issue with its exact error, root cause, and the precise fix to apply.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/jtapieromalambo-ctrl/Signia/llms.txt
Use this file to discover all available pages before exploring further.
model_seq.pkl not found → 503 on camera recognition
model_seq.pkl not found → 503 on camera recognition
ErrorThe CauseThe
/reconocimientos/camara/ page loads but every recognition request immediately returns a 503 response. In Railway logs you may see:reconocimientos/views.py module attempts to load the RandomForest classifier at import time. If reconocimientos/modelo/model_seq.pkl does not exist — because the model has never been trained, or because a Railway deployment wiped the ephemeral filesystem — the module sets the classifier to None and returns 503 for every recognition request.Solution- Log in with a superuser account.
- Navigate to
/admin-videos/. - Upload at least one sign video per label.
- Click Entrenar modelo (Train model).
- Wait for the training process to complete. Training runs in a background daemon thread; the page will indicate when it is done.
CSRF verification failed in production
CSRF verification failed in production
ErrorThis error appears on any POST request — login, registration, translation, recognition — after deploying to Railway.CauseDjango’s CSRF middleware validates that the Redeploy after adding the variable. The CSRF error will disappear immediately on the next deployment.
Origin or Referer header of a POST request matches a domain in CSRF_TRUSTED_ORIGINS. By default, settings.py only populates CSRF_TRUSTED_ORIGINS when RAILWAY_PUBLIC_DOMAIN is set. If that variable is missing, no Railway domain is trusted and every form submission is rejected.SolutionAdd RAILWAY_PUBLIC_DOMAIN to your Railway service’s environment variables:settings.py reads this value and dynamically builds the trusted origins list:MediaPipe WASM not loading in the browser
MediaPipe WASM not loading in the browser
Error (browser console)orThe camera view loads but no hand landmarks are ever detected, and the MediaPipe After correcting the settings, run
HandLandmarker never initialises.CauseThere are two distinct causes for these two errors:-
404: The
STORAGESsetting was changed toManifestStaticFilesStorageorWhiteNoiseStorage. Both backends rename collected files by appending a content hash (e.g.vision_wasm_internal.abc123.wasm). MediaPipe’s internal JavaScript loader constructs the WASM filename with a hard-coded string and cannot follow the manifest, so it requests the original name and gets a 404. -
416: The
.wasmextension was removed fromWHITENOISE_SKIP_COMPRESS_EXTENSIONS. WhiteNoise compressed the WASM binary with gzip, and Chromium’s range-request mechanism cannot satisfy a byte-range request against a gzip stream.
settings.py contains exactly these two entries and has not been modified:python manage.py collectstatic --no-input --clear (Railway does this in build.sh) and redeploy.Recognition freezes or deadlocks under load
Recognition freezes or deadlocks under load
SymptomCamera recognition works for one user but hangs indefinitely or returns empty results when multiple requests arrive concurrently. Railway logs may show Gunicorn worker timeouts.CauseMediaPipe’s Do not refactor this into a module-level singleton. If you see deadlocks, verify that no other part of the codebase imports and reuses a single
HandLandmarker is not thread-safe. A single shared instance accessed by multiple Gunicorn worker threads simultaneously causes deadlocks, dropped frames, and silent hangs. This is a known limitation of the MediaPipe C++ runtime layer.SolutionThe code in reconocimientos/views.py already handles this correctly using threading.local(), which creates a separate HandLandmarker instance for each worker thread:HandLandmarker instance across requests.Neon PostgreSQL SSL connection error
Neon PostgreSQL SSL connection error
ErrororCauseNeon requires all connections to use SSL. If
DATABASE_URL does not include ?sslmode=require, the connection is rejected or dropped.SolutionEnsure your DATABASE_URL ends with ?sslmode=require:settings.py also enforces SSL through the OPTIONS dictionary as a second layer of protection:DISABLE_SERVER_SIDE_CURSORS = True is required for Neon’s connection pooler (PgBouncer). Do not remove it; server-side cursors are incompatible with Neon’s pooling layer and cause InvalidCursorName errors.Emails not being sent (OTP, welcome, password reset)
Emails not being sent (OTP, welcome, password reset)
Error (Django logs)or no error at all — emails are accepted by Django but never arrive in the inbox.CauseThere are three common causes:
BREVO_API_KEYis missing, expired, or copied incorrectly.- The sender address (
DEFAULT_FROM_EMAIL) has not been verified in the Brevo dashboard. EMAIL_HOST_USERis set to an address that differs from the verified sender.
-
Log in to brevo.com → Settings → API Keys and confirm the key is active. Copy it exactly into
BREVO_API_KEY. -
Go to Senders & IP → Senders and verify that
osorioescobardavidfelipe@gmail.com(or the address you set inDEFAULT_FROM_EMAIL) appears with Verified status. - Confirm the environment variables are consistent:
- Check Railway logs for the exact
ApiExceptionmessage — Brevo returns descriptive error bodies that identify the specific problem (rate limit, unverified sender, invalid key, etc.).
Google OAuth redirects to http:// instead of https:// on Railway
Google OAuth redirects to http:// instead of https:// on Railway
Error (Google OAuth consent screen)CauseRailway terminates HTTPS at its edge proxy and forwards requests to Gunicorn over plain HTTP internally. Django sees an HTTP request and generates This tells Django to trust the
http:// redirect URIs. Google’s OAuth service rejects these because the authorised URIs in the Google Cloud Console use https://.Solutionsettings.py already contains the fix:X-Forwarded-Proto: https header that Railway’s proxy injects, causing Django to treat all requests as HTTPS and generate https:// redirect URIs.Verify you have not removed or commented out this line. Additionally, confirm that the authorised redirect URI in Google Cloud Console → APIs & Services → Credentials includes:ffmpeg not found — Whisper transcription fails
ffmpeg not found — Whisper transcription fails
ErrororOccurs when a user submits an audio file via the Do not move or rename the
/traduccion/ module and Whisper cannot locate the ffmpeg binary to decode it.Causefaster-whisper calls ffmpeg as a subprocess. On Railway, ffmpeg is installed by nixpacks.toml and is available on the system PATH. Locally on Windows, the project bundles ffmpeg binaries in the ffmpeg/ directory at the project root. If that directory is moved, renamed, or deleted, local development breaks.Solutiontraduccion/views.py prepends the bundled ffmpeg/ folder to PATH at the top of the module so that Whisper finds it before looking at system paths:ffmpeg/ directory. On Railway, this code is harmless — the directory may not exist, but the system ffmpeg installed by nixpacks.toml is already on PATH and takes precedence.If you are on Linux or macOS for local development and do not have ffmpeg installed globally, install it via your package manager: