Skip to content

10 — Troubleshooting & gotchas

A grab bag of the things that bite developers (especially on day one). Organised by symptom.

Login and auth

"I get logged out the moment I navigate"

Almost always means middleware/redirect.js → getuser hit an exception or got an empty response from /auth/getaccountdetails. Both branches end with:

await app.$auth.logout()
app.$cookies.removeAll()
localStorage.clear()
redirect('/#login')

To diagnose:

  1. Open devtools → Network. Find the /auth/getaccountdetails call.
  2. If it's a 4xx/5xx, the backend rejected your token. Likely an expired or wrong-environment token.
  3. If it's 200 with empty data, the backend sees you but has no account record. Talk to the backend team.
  4. If it never fires at all, your usedetail cookie is missing or malformed. Inspect cookies; clear and retry login.

See 03-auth-and-sessions.md for the full decision tree.

"Cookies aren't being set in local dev"

The @nuxtjs/auth strategy uses sameSite: 'none'; secure: true (in nuxt.config.js). Plain http://localhost rejects secure cookies. Workarounds:

  • Run the dev server behind an HTTPS reverse proxy with a self-signed cert.
  • Verify with the team what the local convention is — there is likely an internal note on this.

"I'm logged in but redirected to login on every page"

@nuxtjs/auth thinks you're logged out even though cookies look present. Common causes:

  • The auth strategy's separate cookies (auth._token.local, auth.strategy, etc.) got cleared while the app's manual cookies (token, usedetail, …) remain. They must agree.
  • A stale currentUrl cookie pointing at a page outside _accid, causing redirect.js to ping-pong.
  • The cookie-domain mismatch when running on a different host than APP_URL.

Hard reset: open devtools → Application → Storage → Clear site data, then reload.

"Account switch leaves stale data on the page"

The store/api.js cache TTL is 5 minutes; switching accounts does not automatically clear it. Dispatch api/clearApiCache on account switch to force the next reads to refetch. See 05-state-management.md.

Routing

"Hitting /contentplanner redirects to /contentplanner indefinitely"

appendUrl middleware reads accountId from localStorage, but middleware/redirect.js only writes the accountId cookie. The localStorage.accountId write does exist — in middleware/head.js — but head.js is not wired into the global middleware chain or any page. So the value gets set only by code paths that explicitly write it (login flows, AccountSwitcher.vue); a user landing via a path that bypasses those will hit the no-op silent failure.

Workaround: localStorage.setItem('accountId', '<your-account-id>') in the console, then reload. Real fix: wire head.js into the middleware chain, or move its localStorage.setItem line into middleware/redirect.js. Coordinate with the team — there may be a reason it's currently unwired.

"landing_url from the backend is sending users to the wrong page"

middleware/redirect.js → getuser reads data.data[0].landing_url from /auth/getaccountdetails and prepends /<accountId> to it. If you see a frontend redirect that doesn't make sense, check what the backend is returning — the frontend is just obeying.

"extendRoutes redirects don't work after a deploy"

nuxt.config.js → router.extendRoutes only adds redirects for /mission-control and /mission-control/overview. New legacy redirects need to be added there (and the deploy redeployed — they're build-time, not runtime).

Polotno editor

"My editor changes don't show up"

You forgot to rebuild the bundle. From the repo root:

cd polotno-editor && yarn build

Then refresh the Nuxt page. The Nuxt dev server has no way to know the editor sources changed because it only sees polotno-bundle.js.

"Editor opens blank, console says createEditor is not a function"

The bundle didn't load. Check:

  1. polotno-bundle.js and polotno-bundle.css exist at the repo root (not inside polotno-editor/).
  2. The page imports them with the right relative path. Pages in pages/_accid/<editor>/_id/ use ../../../../polotno-bundle. If you moved the page, update the path.
  3. The bundle build succeeded — open polotno-editor/dist/... (Parcel's intermediate cache) to see if there were errors.

"window.store is undefined when I try to load JSON"

You called store.loadJSON(...) before createEditor() finished mounting React. Always do createEditor(...) first in mounted(), then call store.toJSON() / store.loadJSON(...) from event handlers (button clicks, route guards), not from mounted() itself.

The bundle dispatches a editor-ready event on window. If you need to wait, listen for that event before touching store.

"Local autosave is loading old content from someone else's design"

The bundle's autosave is keyed by pathname + hash, not by user/account. Two users on the same machine editing different designs at the same path will overwrite each other's autosave. The fix-from-the-app-side is to pass a unique hash in the URL when opening the editor.

State / data fetching

"Data is 5 minutes stale and won't refresh"

store/api.js caches at 5-minute TTL. Either:

await this.$store.dispatch('api/fetchSettings', { force: true })

…or, after a mutation, dispatch clearApiCache and let subsequent reads refetch:

await this.$axios.post('/auth/addOrUpdateSetting', payload)
this.$store.dispatch('api/clearApiCache')

"Network call returned an error but UI thinks it succeeded"

store/api.js actions and the postData/getData helpers in store/index.js swallow exceptions and return cached/empty values. Don't rely on a thrown rejection — check the return value and/or inspect the Network tab. If the action you're calling is one of the cached ones, a returned cached value can mask a real error.

"Vuex user state is empty even though I'm logged in"

The root user state is only populated by the getUserData action, which is rarely dispatched. Use this.$auth.user instead. See 03-auth-and-sessions.md.

Build and CI

"Yarn install is slow / pulls a lot"

Both node_modules directories together are several gigabytes. Network-heavy installs are normal. Don't switch to npm to "fix it" — see 09-conventions.md.

"nuxt: command not found after deploy"

The EFS-mounted node_modules lost its .bin/nuxt symlink. start.sh recreates it on boot, so a container restart should fix it. If it doesn't, the EFS volume is missing or incomplete — escalate.

"Jenkins reports succeeded with warnings (exit 100)"

The pipeline grep-matched a critical-warning pattern in the build log. Open the Teams notification or build console to see which pattern. Common ones:

  • Two component files resolving to the same name — you added a component whose name collides with another. Rename.
  • Module not found — a package.json change wasn't accompanied by yarn.lock update. Re-commit with the fresh lockfile.
  • Icon not found — the editor or main app references an asset that doesn't exist on disk. Add the asset.

See 07-build-and-deploy.md for the full pattern list.

"Build passes locally but fails on Jenkins"

Most common causes, in order:

  1. Missing env var in CI but present in your .env.
  2. Different Node version. Match node:20.18.3-slim.
  3. package.json change without yarn.lock update.
  4. A file you added that's gitignored locally but expected by the build.

Production-only issues

"Site loads but immediately redirects to /#login"

Production-only redirect-to-login usually means the auth cookie failed to set on the production domain. Causes:

  • APP_URL mismatch between what the backend expects and what the frontend serves at.
  • sameSite: 'none'; secure: true cookies failing on HTTP (production should be HTTPS — check the load balancer/CDN).
  • Cookie-domain misconfiguration (cookies set on app.someli.ai but app is loaded from www.someli.ai).

"Large file uploads fail at ~1MB"

Nginx defaults are too small. The deployed nginx.conf sets client_max_body_size 200M and matching timeouts — if you're behind an additional proxy (CDN, ALB), check those too.

"Stripe / Paddle script not loading"

Both are loaded as <script src="https://js.stripe.com/v3/"> / https://cdn.paddle.com/paddle/v2/paddle.js from nuxt.config.js → head.script. A CSP or ad-blocker can suppress them. CSP is not currently set in this repo, so the most likely culprit is a browser extension on the user's side.

Diagnostic shortcuts

A few commands that are useful when debugging:

# What state is the EFS-mounted node_modules in?
ls /usr/src/app/node_modules | wc -l
ls /usr/src/app/polotno-editor/node_modules | wc -l

# Is nuxt actually present?
ls -la /usr/src/app/node_modules/.bin/nuxt

# What environment is this?
grep -E '^API_URL=|^APP_URL=' /usr/src/app/.env || echo "no .env (expected — built into bundle)"

# Recent build log on the deploy host
tail -200 ${DEPLOY_PATH}/build_root.log
tail -200 ${DEPLOY_PATH}/build_polotno.log

# PM2 status
pm2 status
pm2 logs dev_app --lines 200

Where to ask

  • For backend / API behaviour: backend team.
  • For deploy / infra / EFS: ops or whoever owns Jenkins.
  • For Polotno license, design templates, AI keys: verify with the team — there is likely a single owner of the design tooling.
  • For "why is this code structured this way": git blame the relevant file and ask the author or whoever inherited their work.