Troubleshooting
Common issues encountered when running or deploying NextGenPoll, with solutions.
Authentication
MSAL interaction_in_progress Login Loop (Dev)
Symptom: The app redirects to Azure login, completes successfully, returns to the app, and then immediately redirects to login again — looping indefinitely.
Cause: React StrictMode double-fires useEffect in development, creating two concurrent loginRedirect() calls. The second call throws interaction_in_progress, which clears PKCE state, breaking the first call's return flow.
Fix: Already implemented via useRef guard in app/login/page.tsx. If you see this after a code change, verify:
- The
useRefguard (loginInitiated) is still present in the login page. - The MSAL PCA singleton on
window.__NEXTGENPOLL_MSAL__is not being re-created on HMR.
Quick reset: Clear sessionStorage and localStorage in the browser DevTools, then reload.
JWT JwtDecoderInitializationException / NoOpCache
Symptom: Backend logs show JwtDecoderInitializationException and repeated JWKS fetch attempts. Every API request returns 401.
Cause: The JWKS endpoint (ciamlogin.com) was unreachable at startup or took too long to respond, falling back to NoOpCache, causing repeated re-fetches that often time out.
Fix:
- Verify
AZURE_TENANT_IDis correctly set. - Check that
JWT_JWK_CONNECT_TIMEOUT_MSandJWT_JWK_READ_TIMEOUT_MSare high enough (default: 5000ms each). - In Azure App Service, ensure the backend can reach external URLs (check outbound network rules).
- The backend performs a JWKS warm-up probe on startup (
JWT_JWK_WARMUP_ENABLED=true). Check the startup logs for latency.
Redirect URI Mismatch
Symptom: Azure CIAM returns error: AADSTS50011: The redirect URI does not match.
Fix: Ensure the exact redirect URI registered in CIAM matches NEXT_PUBLIC_AZURE_REDIRECT_URI (including protocol, host, port, and path). Common mistakes:
httpvshttps- Trailing slash present/absent
- Missing the
/auth/callbackpath
Database
Flyway Checksum Mismatch
Symptom: Migration V{n} failed — checksum mismatch for migration file.
Cause: A previously-applied migration script was modified.
Fix:
./mvnw flyway:repair
Then restore the original migration content (use git diff or git checkout). Add a new migration to correct the schema if needed.
Flyway Table 'flyway_schema_history' doesn't exist on Fresh DB
Symptom: On a brand-new database, Flyway fails immediately.
Cause: This should not happen with default settings — Flyway creates the history table automatically. If using baselineOnMigrate=true with an existing database, ensure the baseline version is set correctly.
Fix: Run ./mvnw flyway:baseline once against the new database, then flyway:migrate.
JPA Schema Validation Failure at Startup (prod profile)
Symptom: javax.persistence.PersistenceException: Schema-validation: missing column.
Cause: A JPA entity field was added without a corresponding Flyway migration. The prod profile uses ddl-auto=validate.
Fix: Add a migration that creates the missing column. Never use ddl-auto=update in production.
Backend
Port 8080 already in use
Symptom: Backend fails to start with Address already in use: 8080.
Fix:
# Windows — find and kill the process on port 8080
netstat -ano | findstr :8080
taskkill /PID <pid> /F
# Mac / Linux
lsof -i :8080
kill -9 <pid>
Lombok / Java 25 Compilation Warnings or Missing Getters
Symptom: Stale Lombok errors or missing getter/setter methods after adding @Builder.Default to a JPA entity.
Cause: @Builder.Default combined with @Data or @Builder silently breaks getter/setter generation in Java 25.
Fix: For all JPA entity classes, use explicit getters and setters instead of Lombok annotations. Do not use @Builder.Default on entity fields.
If errors persist after fixing: Run Java: Clean Java Language Server Workspace in VS Code command palette, then reload VS Code.
Frontend
npm install Inside a Subdirectory Creates Nested package-lock.json
Symptom: Running npm install inside frontend/ or powerpoint/ creates a new package-lock.json in that directory.
Fix: Always run npm install / npm ci from the monorepo root. Delete any nested package-lock.json and node_modules created inside subdirectories, then run npm ci from root.
Next.js Build Fails — NEXT_PUBLIC_* Variable is Undefined
Symptom: Build fails or the deployed app shows "undefined" for an API URL.
Cause: NEXT_PUBLIC_* variables must be available at build time (not just runtime). They are baked into the JavaScript bundle.
Fix: Ensure all NEXT_PUBLIC_* secrets are set as environment variables in the GitHub Actions Build Frontend step. See CI/CD Pipelines for the complete list.
PowerPoint Add-in
Certificate Error / "The app took too long to load"
Symptom: PowerPoint shows a warning or the task pane is blank.
Fix:
# Re-install the dev certificate
npx office-addin-dev-certs install
Fully close and reopen PowerPoint after running this.
Ribbon Buttons Missing After Sideload (Windows)
Symptom: The add-in was sideloaded successfully but no buttons appear in the ribbon.
Fix: Go to Home → Add-ins in PowerPoint, find NextGenPoll, and click it to complete activation. This is a known Office behaviour on Windows for first-time sideload.
Docker / Database
docker compose up -d Fails — Port 5432 Already in Use
Fix: Stop any existing PostgreSQL instance on port 5432. If you have a local PostgreSQL installation, temporarily stop it:
# Windows
Stop-Service postgresql*
# Mac
brew services stop postgresql
Data Lost After docker compose down -v
down -v removes the pgdata volume, which deletes all data. To reset only the containers without losing data, use:
docker compose down # No -v flag
docker compose up -d
The backend's Flyway migrations will re-run on the next startup and re-seed the data.