Skip to main content

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:

  1. The useRef guard (loginInitiated) is still present in the login page.
  2. 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:

  1. Verify AZURE_TENANT_ID is correctly set.
  2. Check that JWT_JWK_CONNECT_TIMEOUT_MS and JWT_JWK_READ_TIMEOUT_MS are high enough (default: 5000ms each).
  3. In Azure App Service, ensure the backend can reach external URLs (check outbound network rules).
  4. 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:

  • http vs https
  • Trailing slash present/absent
  • Missing the /auth/callback path

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.