3.5 KiB
Common Bugs & Pitfalls
Auth redirect loop (index.html ↔ dashboard.html)
Symptom: Page constantly refreshes between index.html and dashboard.html.
Root cause: index.html line 131 blindly checks localStorage.getItem('pocketbase_auth') — any truthy value (including stale/expired tokens) triggers a redirect to dashboard.html. Dashboard's onAuthStateChanged then detects the invalid token and bounces back to index.html, but the stale token is never cleared from localStorage.
Fix: In every file that redirects unauthenticated users back to index.html, clear the stale token first:
localStorage.removeItem('pocketbase_auth');
window.location.href = 'index.html';
Files that need this: dashboard.js (line 122), appointments.js (line 50), repair-orders.js (line 58).
PocketBase auto-cancellation ("request was auto-cancelled")
Symptom: Creating/updating records fails with "The request was auto-cancelled" or similar abort error.
Root cause: PocketBase SDK auto-cancels requests that share the same requestKey. By default, all create/update calls to the same collection share the same key — a rapid double-click fires two identical requests and the first is aborted.
Fix — two parts:
-
Disable auto-cancellation in
pocketbase.jsby passing{ requestKey: null }to all mutating PocketBase calls:addDoc:pb.collection(collName).create(pbData, { requestKey: null })updateDoc:pb.collection(collName).update(docId, pbData, { requestKey: null })setDoc: both internalupdateandcreatecalls need it
-
Add double-submission guard to form submit handlers — disable the button on first click:
const submitBtn = document.getElementById('submit-create-ro');
if (submitBtn && submitBtn.disabled) return;
if (submitBtn) {
submitBtn.disabled = true;
submitBtn.textContent = 'Creating...';
}
Re-enable the button in BOTH the success path (after form clear/collapse) AND the catch block on error. Forgetting the success path leaves the button permanently disabled after a successful submission.
DuckDNS DNS stale / site unreachable
Symptom: "This site can't be reached" when accessing grajmedia.duckdns.org.
Check order:
dig +short grajmedia.duckdns.org— if returns127.0.0.1, run the DuckDNS updater manually:bash /opt/duckdns/update.sh- The cron job runs every 5 min:
*/5 * * * * /opt/duckdns/update.sh /etc/hostshas127.0.0.1 grajmedia.duckdns.orgfor local hairpin NAT — this is intentional, not a bug
Dashboard Completed counter shows 0 (ro.status vs ro.workStatus)
Symptom: "Completed: 0" on the dashboard Repair Orders Today card, despite having completed orders today.
Root causes (usually BOTH apply):
- Wrong field: Code filters by
ro.status === 'completed'butstatusonly storeswaiter/drop-off. Must usero.workStatus === 'completed'. - Completed orders filtered out at source:
loadRepairOrders()in dashboard.js removes all completed orders fromdashboardData.repairOrdersbefore any counter can see them.
Fix checklist:
- Replace ALL
ro.status === 'completed'withro.workStatus === 'completed' - Replace ALL
ro.status === 'picked-up'withro.workStatus === 'waiting-for-pickup' - Remove the completed-filter from
loadRepairOrders()sodashboardData.repairOrderscontains ALL orders - Each consumer then filters by
ro.workStatusas needed - See
references/status-field-confusion.mdfor the full reference