9699 lines
333 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="Build Power. Not Rent It. Own your digital infrastructure.">
<meta name="author" content="Bunker Operations">
<link rel="canonical" href="https://bnkserve.org/v2/troubleshooting/common-errors/">
<link rel="prev" href="../faq/">
<link rel="next" href="../auth-issues/">
<link rel="icon" href="../../../assets/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.1">
<title>Common Errors - Changemaker Lite</title>
<link rel="stylesheet" href="../../../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../../../assets/stylesheets/palette.ab4e12ef.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Inter:300,300i,400,400i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Inter";--md-code-font:"JetBrains Mono"}</style>
<link rel="stylesheet" href="../../../stylesheets/extra.css">
<link rel="stylesheet" href="../../../stylesheets/home.css">
<link rel="stylesheet" href="../../../assets/css/video-player.css">
<script>__md_scope=new URL("../../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
<meta property="og:type" content="website" />
<meta property="og:title" content="Common Errors - Changemaker Lite" />
<meta property="og:description" content="Build Power. Not Rent It. Own your digital infrastructure." />
<meta property="og:image" content="https://bnkserve.org/assets/images/social/v2/troubleshooting/common-errors.png" />
<meta property="og:image:type" content="image/png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:url" content="https://bnkserve.org/v2/troubleshooting/common-errors/" />
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:title" content="Common Errors - Changemaker Lite" />
<meta property="twitter:description" content="Build Power. Not Rent It. Own your digital infrastructure." />
<meta property="twitter:image" content="https://bnkserve.org/assets/images/social/v2/troubleshooting/common-errors.png" />
</head>
<body dir="ltr" data-md-color-scheme="slate" data-md-color-primary="deep-purple" data-md-color-accent="amber">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#common-errors-and-solutions" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header md-header--shadow md-header--lifted" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="../../.." title="Changemaker Lite" class="md-header__button md-logo" aria-label="Changemaker Lite" data-md-component="logo">
<img src="../../../assets/logo.png" alt="logo">
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
Changemaker Lite
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Common Errors
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="" data-md-color-scheme="slate" data-md-color-primary="deep-purple" data-md-color-accent="amber" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_0">
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_1" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m17.75 4.09-2.53 1.94.91 3.06-2.63-1.81-2.63 1.81.91-3.06-2.53-1.94L12.44 4l1.06-3 1.06 3zm3.5 6.91-1.64 1.25.59 1.98-1.7-1.17-1.7 1.17.59-1.98L15.75 11l2.06-.05L18.5 9l.69 1.95zm-2.28 4.95c.83-.08 1.72 1.1 1.19 1.85-.32.45-.66.87-1.08 1.27C15.17 23 8.84 23 4.94 19.07c-3.91-3.9-3.91-10.24 0-14.14.4-.4.82-.76 1.27-1.08.75-.53 1.93.36 1.85 1.19-.27 2.86.69 5.83 2.89 8.02a9.96 9.96 0 0 0 8.02 2.89m-1.64 2.02a12.08 12.08 0 0 1-7.8-3.47c-2.17-2.19-3.33-5-3.49-7.82-2.81 3.14-2.7 7.96.31 10.98 3.02 3.01 7.84 3.12 10.98.31"/></svg>
</label>
<input class="md-option" data-md-color-media="" data-md-color-scheme="default" data-md-color-primary="deep-purple" data-md-color-accent="amber" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_1">
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_0" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 7a5 5 0 0 1 5 5 5 5 0 0 1-5 5 5 5 0 0 1-5-5 5 5 0 0 1 5-5m0 2a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3m0-7 2.39 3.42C13.65 5.15 12.84 5 12 5s-1.65.15-2.39.42zM3.34 7l4.16-.35A7.2 7.2 0 0 0 5.94 8.5c-.44.74-.69 1.5-.83 2.29zm.02 10 1.76-3.77a7.131 7.131 0 0 0 2.38 4.14zM20.65 7l-1.77 3.79a7.02 7.02 0 0 0-2.38-4.15zm-.01 10-4.14.36c.59-.51 1.12-1.14 1.54-1.86.42-.73.69-1.5.83-2.29zM12 22l-2.41-3.44c.74.27 1.55.44 2.41.44.82 0 1.63-.17 2.37-.44z"/></svg>
</label>
</form>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<a href="javascript:void(0)" class="md-search__icon md-icon" title="Share" aria-label="Share" data-clipboard data-clipboard-text="" data-md-component="search-share" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08"/></svg>
</a>
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
</nav>
<div class="md-search__suggest" data-md-component="search-suggest"></div>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://gitea.bnkops.com/admin/changemaker.lite" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
</div>
<div class="md-source__repository">
changemaker.lite
</div>
</a>
</div>
</nav>
<nav class="md-tabs" aria-label="Tabs" data-md-component="tabs">
<div class="md-grid">
<ul class="md-tabs__list">
<li class="md-tabs__item">
<a href="../../.." class="md-tabs__link">
Home
</a>
</li>
<li class="md-tabs__item md-tabs__item--active">
<a href="../../" class="md-tabs__link">
V2 Documentation
</a>
</li>
<li class="md-tabs__item">
<a href="../../../phil/" class="md-tabs__link">
Philosophy
</a>
</li>
<li class="md-tabs__item">
<a href="../../../v1/" class="md-tabs__link">
V1 Documentation (Legacy)
</a>
</li>
<li class="md-tabs__item">
<a href="../../../blog/" class="md-tabs__link">
Blog
</a>
</li>
</ul>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary md-nav--lifted" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="../../.." title="Changemaker Lite" class="md-nav__button md-logo" aria-label="Changemaker Lite" data-md-component="logo">
<img src="../../../assets/logo.png" alt="logo">
</a>
Changemaker Lite
</label>
<div class="md-nav__source">
<a href="https://gitea.bnkops.com/admin/changemaker.lite" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
</div>
<div class="md-source__repository">
changemaker.lite
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../.." class="md-nav__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2" checked>
<div class="md-nav__link md-nav__container">
<a href="../../" class="md-nav__link ">
<span class="md-ellipsis">
V2 Documentation
</span>
</a>
<label class="md-nav__link " for="__nav_2" id="__nav_2_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_2">
<span class="md-nav__icon md-icon"></span>
V2 Documentation
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_2" >
<div class="md-nav__link md-nav__container">
<a href="../../getting-started/" class="md-nav__link ">
<span class="md-ellipsis">
Getting Started
</span>
</a>
<label class="md-nav__link " for="__nav_2_2" id="__nav_2_2_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_2">
<span class="md-nav__icon md-icon"></span>
Getting Started
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../getting-started/quick-start/" class="md-nav__link">
<span class="md-ellipsis">
Quick Start
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_3" >
<div class="md-nav__link md-nav__container">
<a href="../../architecture/" class="md-nav__link ">
<span class="md-ellipsis">
Architecture
</span>
</a>
<label class="md-nav__link " for="__nav_2_3" id="__nav_2_3_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_3_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_3">
<span class="md-nav__icon md-icon"></span>
Architecture
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../architecture/dual-api/" class="md-nav__link">
<span class="md-ellipsis">
Dual API System
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../architecture/authentication/" class="md-nav__link">
<span class="md-ellipsis">
Authentication & Security
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_4" >
<div class="md-nav__link md-nav__container">
<a href="../../backend/" class="md-nav__link ">
<span class="md-ellipsis">
Backend
</span>
</a>
<label class="md-nav__link " for="__nav_2_4" id="__nav_2_4_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_4_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_4">
<span class="md-nav__icon md-icon"></span>
Backend
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../backend/modules/" class="md-nav__link">
<span class="md-ellipsis">
Modules
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../backend/services/" class="md-nav__link">
<span class="md-ellipsis">
Services
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../backend/middleware/" class="md-nav__link">
<span class="md-ellipsis">
Middleware
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../backend/utilities/" class="md-nav__link">
<span class="md-ellipsis">
Utilities
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_5" >
<div class="md-nav__link md-nav__container">
<a href="../../frontend/" class="md-nav__link ">
<span class="md-ellipsis">
Frontend
</span>
</a>
<label class="md-nav__link " for="__nav_2_5" id="__nav_2_5_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_5_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_5">
<span class="md-nav__icon md-icon"></span>
Frontend
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../frontend/components/" class="md-nav__link">
<span class="md-ellipsis">
Components
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../frontend/layouts/" class="md-nav__link">
<span class="md-ellipsis">
Layouts
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../frontend/pages/" class="md-nav__link">
<span class="md-ellipsis">
Pages
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_6" >
<div class="md-nav__link md-nav__container">
<a href="../../database/" class="md-nav__link ">
<span class="md-ellipsis">
Database
</span>
</a>
<label class="md-nav__link " for="__nav_2_6" id="__nav_2_6_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_6_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_6">
<span class="md-nav__icon md-icon"></span>
Database
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../database/schema/" class="md-nav__link">
<span class="md-ellipsis">
Schema Overview
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../database/migrations/" class="md-nav__link">
<span class="md-ellipsis">
Migrations
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../database/seeding/" class="md-nav__link">
<span class="md-ellipsis">
Seeding
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../database/indexes/" class="md-nav__link">
<span class="md-ellipsis">
Indexes
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../database/models/" class="md-nav__link">
<span class="md-ellipsis">
Models
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_7" >
<div class="md-nav__link md-nav__container">
<a href="../../features/" class="md-nav__link ">
<span class="md-ellipsis">
Features
</span>
</a>
<label class="md-nav__link " for="__nav_2_7" id="__nav_2_7_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_7_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_7">
<span class="md-nav__icon md-icon"></span>
Features
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../features/influence/" class="md-nav__link">
<span class="md-ellipsis">
Influence
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../features/map/" class="md-nav__link">
<span class="md-ellipsis">
Map
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../features/landing-pages/" class="md-nav__link">
<span class="md-ellipsis">
Landing Pages
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../features/email-templates/" class="md-nav__link">
<span class="md-ellipsis">
Email Templates
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../features/media/" class="md-nav__link">
<span class="md-ellipsis">
Media
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../features/newsletter/" class="md-nav__link">
<span class="md-ellipsis">
Newsletter
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../features/observability/" class="md-nav__link">
<span class="md-ellipsis">
Observability
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../features/tunnel/" class="md-nav__link">
<span class="md-ellipsis">
Tunnel
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_8" >
<div class="md-nav__link md-nav__container">
<a href="../../deployment/" class="md-nav__link ">
<span class="md-ellipsis">
Deployment
</span>
</a>
<label class="md-nav__link " for="__nav_2_8" id="__nav_2_8_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_8_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_8">
<span class="md-nav__icon md-icon"></span>
Deployment
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../deployment/docker-compose/" class="md-nav__link">
<span class="md-ellipsis">
Docker Compose
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../deployment/environment-variables/" class="md-nav__link">
<span class="md-ellipsis">
Environment Variables
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../deployment/nginx/" class="md-nav__link">
<span class="md-ellipsis">
Nginx Configuration
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../deployment/ssl-tls/" class="md-nav__link">
<span class="md-ellipsis">
SSL/TLS
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../deployment/tunneling/" class="md-nav__link">
<span class="md-ellipsis">
Tunneling
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../deployment/monitoring-stack/" class="md-nav__link">
<span class="md-ellipsis">
Monitoring Stack
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../deployment/healthchecks/" class="md-nav__link">
<span class="md-ellipsis">
Health Checks
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../deployment/scaling/" class="md-nav__link">
<span class="md-ellipsis">
Scaling
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../deployment/backup-restore/" class="md-nav__link">
<span class="md-ellipsis">
Backup & Restore
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_9" >
<div class="md-nav__link md-nav__container">
<a href="../../development/" class="md-nav__link ">
<span class="md-ellipsis">
Development
</span>
</a>
<label class="md-nav__link " for="__nav_2_9" id="__nav_2_9_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_9_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_9">
<span class="md-nav__icon md-icon"></span>
Development
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../development/local-setup/" class="md-nav__link">
<span class="md-ellipsis">
Local Setup
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../development/docker-workflow/" class="md-nav__link">
<span class="md-ellipsis">
Docker Workflow
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../development/git-workflow/" class="md-nav__link">
<span class="md-ellipsis">
Git Workflow
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../development/npm-commands/" class="md-nav__link">
<span class="md-ellipsis">
NPM Commands
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../development/migrations/" class="md-nav__link">
<span class="md-ellipsis">
Migrations
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../development/typescript/" class="md-nav__link">
<span class="md-ellipsis">
TypeScript
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../development/testing/" class="md-nav__link">
<span class="md-ellipsis">
Testing
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../development/debugging/" class="md-nav__link">
<span class="md-ellipsis">
Debugging
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../development/code-style/" class="md-nav__link">
<span class="md-ellipsis">
Code Style
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_10" >
<div class="md-nav__link md-nav__container">
<a href="../../api-reference/" class="md-nav__link ">
<span class="md-ellipsis">
API Reference
</span>
</a>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_10_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_10">
<span class="md-nav__icon md-icon"></span>
API Reference
</label>
<ul class="md-nav__list" data-md-scrollfix>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_11" >
<div class="md-nav__link md-nav__container">
<a href="../../user-guides/" class="md-nav__link ">
<span class="md-ellipsis">
User Guides
</span>
</a>
<label class="md-nav__link " for="__nav_2_11" id="__nav_2_11_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_11_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_11">
<span class="md-nav__icon md-icon"></span>
User Guides
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../user-guides/admin-guide/" class="md-nav__link">
<span class="md-ellipsis">
Admin Guide
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../user-guides/campaign-manager-guide/" class="md-nav__link">
<span class="md-ellipsis">
Campaign Manager Guide
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../user-guides/map-organizer-guide/" class="md-nav__link">
<span class="md-ellipsis">
Map Organizer Guide
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../user-guides/content-editor-guide/" class="md-nav__link">
<span class="md-ellipsis">
Content Editor Guide
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../user-guides/volunteer-guide/" class="md-nav__link">
<span class="md-ellipsis">
Volunteer Guide
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_12" checked>
<div class="md-nav__link md-nav__container">
<a href="../" class="md-nav__link ">
<span class="md-ellipsis">
Troubleshooting
</span>
</a>
<label class="md-nav__link " for="__nav_2_12" id="__nav_2_12_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_12_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_2_12">
<span class="md-nav__icon md-icon"></span>
Troubleshooting
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../faq/" class="md-nav__link">
<span class="md-ellipsis">
FAQ
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
Common Errors
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Common Errors
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="On this page">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
On this page
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#overview" class="md-nav__link">
<span class="md-ellipsis">
Overview
</span>
</a>
<nav class="md-nav" aria-label="Overview">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#how-to-use-this-guide" class="md-nav__link">
<span class="md-ellipsis">
How to Use This Guide
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#error-severity-levels" class="md-nav__link">
<span class="md-ellipsis">
Error Severity Levels
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#quick-error-lookup" class="md-nav__link">
<span class="md-ellipsis">
Quick Error Lookup
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#authentication-errors" class="md-nav__link">
<span class="md-ellipsis">
Authentication Errors
</span>
</a>
<nav class="md-nav" aria-label="Authentication Errors">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#401-unauthorized" class="md-nav__link">
<span class="md-ellipsis">
401 Unauthorized
</span>
</a>
<nav class="md-nav" aria-label="401 Unauthorized">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#403-forbidden" class="md-nav__link">
<span class="md-ellipsis">
403 Forbidden
</span>
</a>
<nav class="md-nav" aria-label="403 Forbidden">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_1" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_1" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_1" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_1" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#invalid-token" class="md-nav__link">
<span class="md-ellipsis">
Invalid Token
</span>
</a>
<nav class="md-nav" aria-label="Invalid Token">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_2" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_2" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_2" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_2" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#token-expired" class="md-nav__link">
<span class="md-ellipsis">
Token Expired
</span>
</a>
<nav class="md-nav" aria-label="Token Expired">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_3" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_3" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_3" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_3" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#user-not-found" class="md-nav__link">
<span class="md-ellipsis">
User Not Found
</span>
</a>
<nav class="md-nav" aria-label="User Not Found">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_4" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_4" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_4" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_4" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#api-errors" class="md-nav__link">
<span class="md-ellipsis">
API Errors
</span>
</a>
<nav class="md-nav" aria-label="API Errors">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#500-internal-server-error" class="md-nav__link">
<span class="md-ellipsis">
500 Internal Server Error
</span>
</a>
<nav class="md-nav" aria-label="500 Internal Server Error">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_5" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_5" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_5" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_5" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#400-bad-request" class="md-nav__link">
<span class="md-ellipsis">
400 Bad Request
</span>
</a>
<nav class="md-nav" aria-label="400 Bad Request">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_6" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_6" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_6" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_6" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#404-not-found" class="md-nav__link">
<span class="md-ellipsis">
404 Not Found
</span>
</a>
<nav class="md-nav" aria-label="404 Not Found">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_7" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_7" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_7" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_7" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#422-unprocessable-entity" class="md-nav__link">
<span class="md-ellipsis">
422 Unprocessable Entity
</span>
</a>
<nav class="md-nav" aria-label="422 Unprocessable Entity">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_8" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_8" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_8" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_8" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#database-errors" class="md-nav__link">
<span class="md-ellipsis">
Database Errors
</span>
</a>
<nav class="md-nav" aria-label="Database Errors">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#connection-refused" class="md-nav__link">
<span class="md-ellipsis">
Connection Refused
</span>
</a>
<nav class="md-nav" aria-label="Connection Refused">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_9" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_9" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_9" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_9" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#too-many-connections" class="md-nav__link">
<span class="md-ellipsis">
Too Many Connections
</span>
</a>
<nav class="md-nav" aria-label="Too Many Connections">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_10" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_10" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_10" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_10" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#unique-constraint-violation" class="md-nav__link">
<span class="md-ellipsis">
Unique Constraint Violation
</span>
</a>
<nav class="md-nav" aria-label="Unique Constraint Violation">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_11" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_11" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_11" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_11" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#foreign-key-constraint" class="md-nav__link">
<span class="md-ellipsis">
Foreign Key Constraint
</span>
</a>
<nav class="md-nav" aria-label="Foreign Key Constraint">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_12" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_12" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_12" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_12" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#frontend-errors" class="md-nav__link">
<span class="md-ellipsis">
Frontend Errors
</span>
</a>
<nav class="md-nav" aria-label="Frontend Errors">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#network-error" class="md-nav__link">
<span class="md-ellipsis">
Network Error
</span>
</a>
<nav class="md-nav" aria-label="Network Error">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_13" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_13" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_13" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_13" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#cors-errors" class="md-nav__link">
<span class="md-ellipsis">
CORS Errors
</span>
</a>
<nav class="md-nav" aria-label="CORS Errors">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_14" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_14" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_14" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_14" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#module-not-found" class="md-nav__link">
<span class="md-ellipsis">
Module Not Found
</span>
</a>
<nav class="md-nav" aria-label="Module Not Found">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_15" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_15" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_15" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_15" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#hydration-errors" class="md-nav__link">
<span class="md-ellipsis">
Hydration Errors
</span>
</a>
<nav class="md-nav" aria-label="Hydration Errors">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_16" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_16" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_16" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_16" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#file-upload-errors" class="md-nav__link">
<span class="md-ellipsis">
File Upload Errors
</span>
</a>
<nav class="md-nav" aria-label="File Upload Errors">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#file-too-large" class="md-nav__link">
<span class="md-ellipsis">
File Too Large
</span>
</a>
<nav class="md-nav" aria-label="File Too Large">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_17" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_17" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_17" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_17" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#invalid-file-type" class="md-nav__link">
<span class="md-ellipsis">
Invalid File Type
</span>
</a>
<nav class="md-nav" aria-label="Invalid File Type">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_18" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_18" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_18" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_18" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#upload-timeout" class="md-nav__link">
<span class="md-ellipsis">
Upload Timeout
</span>
</a>
<nav class="md-nav" aria-label="Upload Timeout">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_19" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_19" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_19" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_19" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#email-errors" class="md-nav__link">
<span class="md-ellipsis">
Email Errors
</span>
</a>
<nav class="md-nav" aria-label="Email Errors">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#smtp-connection-failed" class="md-nav__link">
<span class="md-ellipsis">
SMTP Connection Failed
</span>
</a>
<nav class="md-nav" aria-label="SMTP Connection Failed">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_20" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_20" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_20" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_20" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#template-not-found" class="md-nav__link">
<span class="md-ellipsis">
Template Not Found
</span>
</a>
<nav class="md-nav" aria-label="Template Not Found">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_21" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_21" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_21" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_21" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#variable-missing" class="md-nav__link">
<span class="md-ellipsis">
Variable Missing
</span>
</a>
<nav class="md-nav" aria-label="Variable Missing">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_22" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_22" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_22" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_22" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#quick-reference-table" class="md-nav__link">
<span class="md-ellipsis">
Quick Reference Table
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#when-to-report-bugs" class="md-nav__link">
<span class="md-ellipsis">
When to Report Bugs
</span>
</a>
<nav class="md-nav" aria-label="When to Report Bugs">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#report-these" class="md-nav__link">
<span class="md-ellipsis">
Report These
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#dont-report-these" class="md-nav__link">
<span class="md-ellipsis">
Don't Report These
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#how-to-report" class="md-nav__link">
<span class="md-ellipsis">
How to Report
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#related-documentation" class="md-nav__link">
<span class="md-ellipsis">
Related Documentation
</span>
</a>
<nav class="md-nav" aria-label="Related Documentation">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#general-documentation" class="md-nav__link">
<span class="md-ellipsis">
General Documentation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#specific-troubleshooting" class="md-nav__link">
<span class="md-ellipsis">
Specific Troubleshooting
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#support" class="md-nav__link">
<span class="md-ellipsis">
Support
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../auth-issues/" class="md-nav__link">
<span class="md-ellipsis">
Auth Issues
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../database-issues/" class="md-nav__link">
<span class="md-ellipsis">
Database Issues
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../docker-issues/" class="md-nav__link">
<span class="md-ellipsis">
Docker Issues
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../email-issues/" class="md-nav__link">
<span class="md-ellipsis">
Email Issues
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../geocoding-issues/" class="md-nav__link">
<span class="md-ellipsis">
Geocoding Issues
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../monitoring-issues/" class="md-nav__link">
<span class="md-ellipsis">
Monitoring Issues
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../performance-optimization/" class="md-nav__link">
<span class="md-ellipsis">
Performance Optimization
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_13" >
<div class="md-nav__link md-nav__container">
<a href="../../migration/" class="md-nav__link ">
<span class="md-ellipsis">
Migration
</span>
</a>
<label class="md-nav__link " for="__nav_2_13" id="__nav_2_13_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_13_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_13">
<span class="md-nav__icon md-icon"></span>
Migration
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../migration/feature-parity/" class="md-nav__link">
<span class="md-ellipsis">
Feature Parity
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../migration/breaking-changes/" class="md-nav__link">
<span class="md-ellipsis">
Breaking Changes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../migration/api-changes/" class="md-nav__link">
<span class="md-ellipsis">
API Changes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../migration/data-migration/" class="md-nav__link">
<span class="md-ellipsis">
Data Migration
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_14" >
<div class="md-nav__link md-nav__container">
<a href="../../contributing/" class="md-nav__link ">
<span class="md-ellipsis">
Contributing
</span>
</a>
<label class="md-nav__link " for="__nav_2_14" id="__nav_2_14_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_14_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_14">
<span class="md-nav__icon md-icon"></span>
Contributing
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../contributing/development-setup/" class="md-nav__link">
<span class="md-ellipsis">
Development Setup
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../contributing/code-of-conduct/" class="md-nav__link">
<span class="md-ellipsis">
Code of Conduct
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../contributing/pull-requests/" class="md-nav__link">
<span class="md-ellipsis">
Pull Requests
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../contributing/roadmap/" class="md-nav__link">
<span class="md-ellipsis">
Roadmap
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../../phil/" class="md-nav__link">
<span class="md-ellipsis">
Philosophy
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../../v1/" class="md-nav__link">
<span class="md-ellipsis">
V1 Documentation (Legacy)
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../../blog/" class="md-nav__link">
<span class="md-ellipsis">
Blog
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="On this page">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
On this page
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#overview" class="md-nav__link">
<span class="md-ellipsis">
Overview
</span>
</a>
<nav class="md-nav" aria-label="Overview">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#how-to-use-this-guide" class="md-nav__link">
<span class="md-ellipsis">
How to Use This Guide
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#error-severity-levels" class="md-nav__link">
<span class="md-ellipsis">
Error Severity Levels
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#quick-error-lookup" class="md-nav__link">
<span class="md-ellipsis">
Quick Error Lookup
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#authentication-errors" class="md-nav__link">
<span class="md-ellipsis">
Authentication Errors
</span>
</a>
<nav class="md-nav" aria-label="Authentication Errors">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#401-unauthorized" class="md-nav__link">
<span class="md-ellipsis">
401 Unauthorized
</span>
</a>
<nav class="md-nav" aria-label="401 Unauthorized">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#403-forbidden" class="md-nav__link">
<span class="md-ellipsis">
403 Forbidden
</span>
</a>
<nav class="md-nav" aria-label="403 Forbidden">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_1" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_1" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_1" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_1" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#invalid-token" class="md-nav__link">
<span class="md-ellipsis">
Invalid Token
</span>
</a>
<nav class="md-nav" aria-label="Invalid Token">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_2" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_2" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_2" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_2" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#token-expired" class="md-nav__link">
<span class="md-ellipsis">
Token Expired
</span>
</a>
<nav class="md-nav" aria-label="Token Expired">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_3" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_3" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_3" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_3" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#user-not-found" class="md-nav__link">
<span class="md-ellipsis">
User Not Found
</span>
</a>
<nav class="md-nav" aria-label="User Not Found">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_4" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_4" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_4" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_4" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#api-errors" class="md-nav__link">
<span class="md-ellipsis">
API Errors
</span>
</a>
<nav class="md-nav" aria-label="API Errors">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#500-internal-server-error" class="md-nav__link">
<span class="md-ellipsis">
500 Internal Server Error
</span>
</a>
<nav class="md-nav" aria-label="500 Internal Server Error">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_5" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_5" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_5" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_5" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#400-bad-request" class="md-nav__link">
<span class="md-ellipsis">
400 Bad Request
</span>
</a>
<nav class="md-nav" aria-label="400 Bad Request">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_6" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_6" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_6" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_6" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#404-not-found" class="md-nav__link">
<span class="md-ellipsis">
404 Not Found
</span>
</a>
<nav class="md-nav" aria-label="404 Not Found">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_7" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_7" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_7" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_7" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#422-unprocessable-entity" class="md-nav__link">
<span class="md-ellipsis">
422 Unprocessable Entity
</span>
</a>
<nav class="md-nav" aria-label="422 Unprocessable Entity">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_8" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_8" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_8" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_8" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#database-errors" class="md-nav__link">
<span class="md-ellipsis">
Database Errors
</span>
</a>
<nav class="md-nav" aria-label="Database Errors">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#connection-refused" class="md-nav__link">
<span class="md-ellipsis">
Connection Refused
</span>
</a>
<nav class="md-nav" aria-label="Connection Refused">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_9" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_9" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_9" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_9" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#too-many-connections" class="md-nav__link">
<span class="md-ellipsis">
Too Many Connections
</span>
</a>
<nav class="md-nav" aria-label="Too Many Connections">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_10" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_10" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_10" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_10" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#unique-constraint-violation" class="md-nav__link">
<span class="md-ellipsis">
Unique Constraint Violation
</span>
</a>
<nav class="md-nav" aria-label="Unique Constraint Violation">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_11" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_11" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_11" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_11" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#foreign-key-constraint" class="md-nav__link">
<span class="md-ellipsis">
Foreign Key Constraint
</span>
</a>
<nav class="md-nav" aria-label="Foreign Key Constraint">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_12" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_12" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_12" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_12" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#frontend-errors" class="md-nav__link">
<span class="md-ellipsis">
Frontend Errors
</span>
</a>
<nav class="md-nav" aria-label="Frontend Errors">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#network-error" class="md-nav__link">
<span class="md-ellipsis">
Network Error
</span>
</a>
<nav class="md-nav" aria-label="Network Error">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_13" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_13" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_13" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_13" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#cors-errors" class="md-nav__link">
<span class="md-ellipsis">
CORS Errors
</span>
</a>
<nav class="md-nav" aria-label="CORS Errors">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_14" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_14" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_14" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_14" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#module-not-found" class="md-nav__link">
<span class="md-ellipsis">
Module Not Found
</span>
</a>
<nav class="md-nav" aria-label="Module Not Found">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_15" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_15" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_15" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_15" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#hydration-errors" class="md-nav__link">
<span class="md-ellipsis">
Hydration Errors
</span>
</a>
<nav class="md-nav" aria-label="Hydration Errors">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_16" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_16" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_16" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_16" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#file-upload-errors" class="md-nav__link">
<span class="md-ellipsis">
File Upload Errors
</span>
</a>
<nav class="md-nav" aria-label="File Upload Errors">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#file-too-large" class="md-nav__link">
<span class="md-ellipsis">
File Too Large
</span>
</a>
<nav class="md-nav" aria-label="File Too Large">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_17" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_17" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_17" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_17" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#invalid-file-type" class="md-nav__link">
<span class="md-ellipsis">
Invalid File Type
</span>
</a>
<nav class="md-nav" aria-label="Invalid File Type">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_18" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_18" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_18" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_18" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#upload-timeout" class="md-nav__link">
<span class="md-ellipsis">
Upload Timeout
</span>
</a>
<nav class="md-nav" aria-label="Upload Timeout">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_19" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_19" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_19" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_19" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#email-errors" class="md-nav__link">
<span class="md-ellipsis">
Email Errors
</span>
</a>
<nav class="md-nav" aria-label="Email Errors">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#smtp-connection-failed" class="md-nav__link">
<span class="md-ellipsis">
SMTP Connection Failed
</span>
</a>
<nav class="md-nav" aria-label="SMTP Connection Failed">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_20" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_20" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_20" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_20" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#template-not-found" class="md-nav__link">
<span class="md-ellipsis">
Template Not Found
</span>
</a>
<nav class="md-nav" aria-label="Template Not Found">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_21" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_21" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_21" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_21" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#variable-missing" class="md-nav__link">
<span class="md-ellipsis">
Variable Missing
</span>
</a>
<nav class="md-nav" aria-label="Variable Missing">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#symptoms_22" class="md-nav__link">
<span class="md-ellipsis">
Symptoms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#common-causes_22" class="md-nav__link">
<span class="md-ellipsis">
Common Causes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#solutions_22" class="md-nav__link">
<span class="md-ellipsis">
Solutions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#prevention_22" class="md-nav__link">
<span class="md-ellipsis">
Prevention
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#quick-reference-table" class="md-nav__link">
<span class="md-ellipsis">
Quick Reference Table
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#when-to-report-bugs" class="md-nav__link">
<span class="md-ellipsis">
When to Report Bugs
</span>
</a>
<nav class="md-nav" aria-label="When to Report Bugs">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#report-these" class="md-nav__link">
<span class="md-ellipsis">
Report These
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#dont-report-these" class="md-nav__link">
<span class="md-ellipsis">
Don't Report These
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#how-to-report" class="md-nav__link">
<span class="md-ellipsis">
How to Report
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#related-documentation" class="md-nav__link">
<span class="md-ellipsis">
Related Documentation
</span>
</a>
<nav class="md-nav" aria-label="Related Documentation">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#general-documentation" class="md-nav__link">
<span class="md-ellipsis">
General Documentation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#specific-troubleshooting" class="md-nav__link">
<span class="md-ellipsis">
Specific Troubleshooting
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#support" class="md-nav__link">
<span class="md-ellipsis">
Support
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<nav class="md-path" aria-label="Navigation" >
<ol class="md-path__list">
<li class="md-path__item">
<a href="../../.." class="md-path__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-path__item">
<a href="../../" class="md-path__link">
<span class="md-ellipsis">
V2 Documentation
</span>
</a>
</li>
<li class="md-path__item">
<a href="../" class="md-path__link">
<span class="md-ellipsis">
Troubleshooting
</span>
</a>
</li>
</ol>
</nav>
<article class="md-content__inner md-typeset">
<a href="https://gitea.bnkops.com/admin/changemaker.lite/src/branch/main/mkdocs/docs/v2/troubleshooting/common-errors.md" title="Edit this page" class="md-content__button md-icon" rel="edit">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 20H6V4h7v5h5v3.1l2-2V8l-6-6H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h4zm10.2-7c.1 0 .3.1.4.2l1.3 1.3c.2.2.2.6 0 .8l-1 1-2.1-2.1 1-1c.1-.1.2-.2.4-.2m0 3.9L14.1 23H12v-2.1l6.1-6.1z"/></svg>
</a>
<a href="https://gitea.bnkops.com/admin/changemaker.lite/src/branch/main/mkdocs/docs/v2/troubleshooting/common-errors.md" title="View source of this page" class="md-content__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 18c.56 0 1 .44 1 1s-.44 1-1 1-1-.44-1-1 .44-1 1-1m0-3c-2.73 0-5.06 1.66-6 4 .94 2.34 3.27 4 6 4s5.06-1.66 6-4c-.94-2.34-3.27-4-6-4m0 6.5a2.5 2.5 0 0 1-2.5-2.5 2.5 2.5 0 0 1 2.5-2.5 2.5 2.5 0 0 1 2.5 2.5 2.5 2.5 0 0 1-2.5 2.5M9.27 20H6V4h7v5h5v4.07c.7.08 1.36.25 2 .49V8l-6-6H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h4.5a8.2 8.2 0 0 1-1.23-2"/></svg>
</a>
<h1 id="common-errors-and-solutions">Common Errors and Solutions<a class="headerlink" href="#common-errors-and-solutions" title="Permanent link">&para;</a></h1>
<p>This guide covers the most frequently encountered errors in Changemaker Lite V2 and their solutions.</p>
<h2 id="overview">Overview<a class="headerlink" href="#overview" title="Permanent link">&para;</a></h2>
<h3 id="how-to-use-this-guide">How to Use This Guide<a class="headerlink" href="#how-to-use-this-guide" title="Permanent link">&para;</a></h3>
<ol>
<li><strong>Find your error</strong> - Use the error code or message to locate the section</li>
<li><strong>Diagnose</strong> - Read the symptoms and causes</li>
<li><strong>Apply solution</strong> - Follow step-by-step instructions</li>
<li><strong>Prevent recurrence</strong> - Implement preventive measures</li>
</ol>
<h3 id="error-severity-levels">Error Severity Levels<a class="headerlink" href="#error-severity-levels" title="Permanent link">&para;</a></h3>
<table>
<thead>
<tr>
<th>Level</th>
<th>Icon</th>
<th>Meaning</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Critical</strong></td>
<td>🔴</td>
<td>System down or data at risk</td>
<td>Fix immediately</td>
</tr>
<tr>
<td><strong>High</strong></td>
<td>🟠</td>
<td>Feature unavailable</td>
<td>Fix within hours</td>
</tr>
<tr>
<td><strong>Medium</strong></td>
<td>🟡</td>
<td>Degraded performance</td>
<td>Fix within days</td>
</tr>
<tr>
<td><strong>Low</strong></td>
<td>🟢</td>
<td>Minor inconvenience</td>
<td>Fix when convenient</td>
</tr>
</tbody>
</table>
<h3 id="quick-error-lookup">Quick Error Lookup<a class="headerlink" href="#quick-error-lookup" title="Permanent link">&para;</a></h3>
<table>
<thead>
<tr>
<th>Error Code</th>
<th>Category</th>
<th>Page</th>
</tr>
</thead>
<tbody>
<tr>
<td>401</td>
<td>Authentication</td>
<td><a href="#401-unauthorized">Link</a></td>
</tr>
<tr>
<td>403</td>
<td>Authorization</td>
<td><a href="#403-forbidden">Link</a></td>
</tr>
<tr>
<td>404</td>
<td>Not Found</td>
<td><a href="#404-not-found">Link</a></td>
</tr>
<tr>
<td>422</td>
<td>Validation</td>
<td><a href="#422-unprocessable-entity">Link</a></td>
</tr>
<tr>
<td>500</td>
<td>Server Error</td>
<td><a href="#500-internal-server-error">Link</a></td>
</tr>
<tr>
<td>CORS</td>
<td>Frontend</td>
<td><a href="#cors-errors">Link</a></td>
</tr>
<tr>
<td>ECONNREFUSED</td>
<td>Database</td>
<td><a href="#connection-refused">Link</a></td>
</tr>
</tbody>
</table>
<hr />
<h2 id="authentication-errors">Authentication Errors<a class="headerlink" href="#authentication-errors" title="Permanent link">&para;</a></h2>
<h3 id="401-unauthorized">401 Unauthorized<a class="headerlink" href="#401-unauthorized" title="Permanent link">&para;</a></h3>
<p><strong>Severity:</strong> 🟠 High</p>
<h4 id="symptoms">Symptoms<a class="headerlink" href="#symptoms" title="Permanent link">&para;</a></h4>
<div class="language-json highlight"><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="p">{</span>
</span><span id="__span-0-2"><a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a><span class="w"> </span><span class="nt">&quot;error&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Unauthorized&quot;</span><span class="p">,</span>
</span><span id="__span-0-3"><a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a><span class="w"> </span><span class="nt">&quot;message&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Invalid or missing token&quot;</span>
</span><span id="__span-0-4"><a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a><span class="p">}</span>
</span></code></pre></div>
<p>Browser console:
<div class="language-text highlight"><pre><span></span><code><span id="__span-1-1"><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a>Error: Request failed with status code 401
</span></code></pre></div></p>
<h4 id="common-causes">Common Causes<a class="headerlink" href="#common-causes" title="Permanent link">&para;</a></h4>
<ol>
<li><strong>Missing token</strong> - No Authorization header sent</li>
<li><strong>Expired token</strong> - Access token older than 15 minutes</li>
<li><strong>Invalid token</strong> - Corrupted or tampered token</li>
<li><strong>Wrong environment</strong> - Token from dev used in production</li>
</ol>
<h4 id="solutions">Solutions<a class="headerlink" href="#solutions" title="Permanent link">&para;</a></h4>
<p><strong>Solution 1: Check if logged in</strong></p>
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-2-1"><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a><span class="c1">// In browser console</span>
</span><span id="__span-2-2"><a id="__codelineno-2-2" name="__codelineno-2-2" href="#__codelineno-2-2"></a><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">localStorage</span><span class="p">.</span><span class="nx">getItem</span><span class="p">(</span><span class="s1">&#39;auth-storage&#39;</span><span class="p">));</span>
</span></code></pre></div>
<p>If null or missing <code>accessToken</code>, you need to log in again.</p>
<p><strong>Solution 2: Refresh token</strong></p>
<p>The frontend automatically refreshes tokens. If this fails:</p>
<ol>
<li>Log out completely</li>
<li>Clear localStorage: <code>localStorage.clear()</code></li>
<li>Log in again</li>
</ol>
<p><strong>Solution 3: Verify API configuration</strong></p>
<p>Check <code>admin/.env</code>:</p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-3-1"><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a><span class="nv">VITE_API_URL</span><span class="o">=</span>http://localhost:4000<span class="w"> </span><span class="c1"># Must match actual API URL</span>
</span></code></pre></div>
<p><strong>Solution 4: Check token expiration</strong></p>
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-4-1"><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a><span class="c1">// In browser console</span>
</span><span id="__span-4-2"><a id="__codelineno-4-2" name="__codelineno-4-2" href="#__codelineno-4-2"></a><span class="kd">const</span><span class="w"> </span><span class="nx">storage</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">localStorage</span><span class="p">.</span><span class="nx">getItem</span><span class="p">(</span><span class="s1">&#39;auth-storage&#39;</span><span class="p">));</span>
</span><span id="__span-4-3"><a id="__codelineno-4-3" name="__codelineno-4-3" href="#__codelineno-4-3"></a><span class="kd">const</span><span class="w"> </span><span class="nx">payload</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">atob</span><span class="p">(</span><span class="nx">storage</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">accessToken</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">&#39;.&#39;</span><span class="p">)[</span><span class="mf">1</span><span class="p">]));</span>
</span><span id="__span-4-4"><a id="__codelineno-4-4" name="__codelineno-4-4" href="#__codelineno-4-4"></a><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;Token expires:&#39;</span><span class="p">,</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nb">Date</span><span class="p">(</span><span class="nx">payload</span><span class="p">.</span><span class="nx">exp</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mf">1000</span><span class="p">));</span>
</span><span id="__span-4-5"><a id="__codelineno-4-5" name="__codelineno-4-5" href="#__codelineno-4-5"></a><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;Current time:&#39;</span><span class="p">,</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nb">Date</span><span class="p">());</span>
</span></code></pre></div>
<p>If expired, the refresh interceptor should handle this. If not working:</p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-5-1"><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a><span class="c1"># Check API logs</span>
</span><span id="__span-5-2"><a id="__codelineno-5-2" name="__codelineno-5-2" href="#__codelineno-5-2"></a>docker<span class="w"> </span>compose<span class="w"> </span>logs<span class="w"> </span>api<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span><span class="s2">&quot;refresh&quot;</span>
</span></code></pre></div>
<h4 id="prevention">Prevention<a class="headerlink" href="#prevention" title="Permanent link">&para;</a></h4>
<ul>
<li><strong>Auto-refresh works</strong> - Frontend handles token refresh automatically</li>
<li><strong>Long sessions</strong> - Refresh tokens valid for 7 days</li>
<li><strong>Activity-based</strong> - Tokens refresh on API calls</li>
<li><strong>Clear error handling</strong> - Frontend redirects to login on failure</li>
</ul>
<div class="admonition warning">
<p class="admonition-title">Security Note</p>
<p>401 errors may return generic messages to prevent user enumeration. This is intentional security behavior.</p>
</div>
<hr />
<h3 id="403-forbidden">403 Forbidden<a class="headerlink" href="#403-forbidden" title="Permanent link">&para;</a></h3>
<p><strong>Severity:</strong> 🟠 High</p>
<h4 id="symptoms_1">Symptoms<a class="headerlink" href="#symptoms_1" title="Permanent link">&para;</a></h4>
<div class="language-json highlight"><pre><span></span><code><span id="__span-6-1"><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a><span class="p">{</span>
</span><span id="__span-6-2"><a id="__codelineno-6-2" name="__codelineno-6-2" href="#__codelineno-6-2"></a><span class="w"> </span><span class="nt">&quot;error&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Forbidden&quot;</span><span class="p">,</span>
</span><span id="__span-6-3"><a id="__codelineno-6-3" name="__codelineno-6-3" href="#__codelineno-6-3"></a><span class="w"> </span><span class="nt">&quot;message&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Insufficient permissions&quot;</span>
</span><span id="__span-6-4"><a id="__codelineno-6-4" name="__codelineno-6-4" href="#__codelineno-6-4"></a><span class="p">}</span>
</span></code></pre></div>
<p>Or role-specific:
<div class="language-json highlight"><pre><span></span><code><span id="__span-7-1"><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a><span class="p">{</span>
</span><span id="__span-7-2"><a id="__codelineno-7-2" name="__codelineno-7-2" href="#__codelineno-7-2"></a><span class="w"> </span><span class="nt">&quot;error&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Forbidden&quot;</span><span class="p">,</span>
</span><span id="__span-7-3"><a id="__codelineno-7-3" name="__codelineno-7-3" href="#__codelineno-7-3"></a><span class="w"> </span><span class="nt">&quot;message&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Requires one of: SUPER_ADMIN, MAP_ADMIN&quot;</span>
</span><span id="__span-7-4"><a id="__codelineno-7-4" name="__codelineno-7-4" href="#__codelineno-7-4"></a><span class="p">}</span>
</span></code></pre></div></p>
<h4 id="common-causes_1">Common Causes<a class="headerlink" href="#common-causes_1" title="Permanent link">&para;</a></h4>
<ol>
<li><strong>Wrong role</strong> - User lacks required role</li>
<li><strong>TEMP user</strong> - Temporary users restricted from most features</li>
<li><strong>Feature disabled</strong> - Feature flag not enabled</li>
<li><strong>Wrong endpoint</strong> - Using admin endpoint as public user</li>
</ol>
<h4 id="solutions_1">Solutions<a class="headerlink" href="#solutions_1" title="Permanent link">&para;</a></h4>
<p><strong>Solution 1: Check user role</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-8-1"><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a><span class="c1"># In database</span>
</span><span id="__span-8-2"><a id="__codelineno-8-2" name="__codelineno-8-2" href="#__codelineno-8-2"></a>docker<span class="w"> </span>compose<span class="w"> </span><span class="nb">exec</span><span class="w"> </span>v2-postgres<span class="w"> </span>psql<span class="w"> </span>-U<span class="w"> </span>changemaker<span class="w"> </span>-d<span class="w"> </span>changemaker_v2<span class="w"> </span><span class="se">\</span>
</span><span id="__span-8-3"><a id="__codelineno-8-3" name="__codelineno-8-3" href="#__codelineno-8-3"></a><span class="w"> </span>-c<span class="w"> </span><span class="s2">&quot;SELECT email, role FROM \&quot;User\&quot; WHERE email = &#39;your@email.com&#39;;&quot;</span>
</span></code></pre></div>
<p><strong>Solution 2: Update user role</strong></p>
<div class="language-sql highlight"><pre><span></span><code><span id="__span-9-1"><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a><span class="c1">-- Via Prisma Studio (recommended)</span>
</span><span id="__span-9-2"><a id="__codelineno-9-2" name="__codelineno-9-2" href="#__codelineno-9-2"></a><span class="n">docker</span><span class="w"> </span><span class="n">compose</span><span class="w"> </span><span class="k">exec</span><span class="w"> </span><span class="n">api</span><span class="w"> </span><span class="n">npx</span><span class="w"> </span><span class="n">prisma</span><span class="w"> </span><span class="n">studio</span>
</span><span id="__span-9-3"><a id="__codelineno-9-3" name="__codelineno-9-3" href="#__codelineno-9-3"></a><span class="c1">-- Navigate to User table, edit role</span>
</span><span id="__span-9-4"><a id="__codelineno-9-4" name="__codelineno-9-4" href="#__codelineno-9-4"></a>
</span><span id="__span-9-5"><a id="__codelineno-9-5" name="__codelineno-9-5" href="#__codelineno-9-5"></a><span class="c1">-- Or via SQL</span>
</span><span id="__span-9-6"><a id="__codelineno-9-6" name="__codelineno-9-6" href="#__codelineno-9-6"></a><span class="n">docker</span><span class="w"> </span><span class="n">compose</span><span class="w"> </span><span class="k">exec</span><span class="w"> </span><span class="n">v2</span><span class="o">-</span><span class="n">postgres</span><span class="w"> </span><span class="n">psql</span><span class="w"> </span><span class="o">-</span><span class="n">U</span><span class="w"> </span><span class="n">changemaker</span><span class="w"> </span><span class="o">-</span><span class="n">d</span><span class="w"> </span><span class="n">changemaker_v2</span><span class="w"> </span><span class="err">\</span>
</span><span id="__span-9-7"><a id="__codelineno-9-7" name="__codelineno-9-7" href="#__codelineno-9-7"></a><span class="w"> </span><span class="o">-</span><span class="k">c</span><span class="w"> </span><span class="ss">&quot;UPDATE \&quot;</span><span class="k">User</span><span class="err">\</span><span class="ss">&quot; SET role = &#39;MAP_ADMIN&#39; WHERE email = &#39;your@email.com&#39;;&quot;</span>
</span></code></pre></div>
<p><strong>Solution 3: Check feature flags</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-10-1"><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a><span class="c1"># In API logs</span>
</span><span id="__span-10-2"><a id="__codelineno-10-2" name="__codelineno-10-2" href="#__codelineno-10-2"></a>docker<span class="w"> </span>compose<span class="w"> </span>logs<span class="w"> </span>api<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span><span class="s2">&quot;ENABLE_&quot;</span>
</span><span id="__span-10-3"><a id="__codelineno-10-3" name="__codelineno-10-3" href="#__codelineno-10-3"></a>
</span><span id="__span-10-4"><a id="__codelineno-10-4" name="__codelineno-10-4" href="#__codelineno-10-4"></a><span class="c1"># Check .env</span>
</span><span id="__span-10-5"><a id="__codelineno-10-5" name="__codelineno-10-5" href="#__codelineno-10-5"></a>cat<span class="w"> </span>.env<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>ENABLE
</span></code></pre></div>
<p><strong>Solution 4: Verify endpoint permissions</strong></p>
<p>Check <code>api/src/modules/*/routes.ts</code>:</p>
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-11-1"><a id="__codelineno-11-1" name="__codelineno-11-1" href="#__codelineno-11-1"></a><span class="c1">// Admin endpoint</span>
</span><span id="__span-11-2"><a id="__codelineno-11-2" name="__codelineno-11-2" href="#__codelineno-11-2"></a><span class="nx">router</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">,</span><span class="w"> </span><span class="nx">authenticate</span><span class="p">,</span><span class="w"> </span><span class="nx">requireRole</span><span class="p">(</span><span class="s1">&#39;SUPER_ADMIN&#39;</span><span class="p">),</span><span class="w"> </span><span class="p">...);</span>
</span><span id="__span-11-3"><a id="__codelineno-11-3" name="__codelineno-11-3" href="#__codelineno-11-3"></a>
</span><span id="__span-11-4"><a id="__codelineno-11-4" name="__codelineno-11-4" href="#__codelineno-11-4"></a><span class="c1">// Public endpoint (no auth)</span>
</span><span id="__span-11-5"><a id="__codelineno-11-5" name="__codelineno-11-5" href="#__codelineno-11-5"></a><span class="nx">router</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;/public&#39;</span><span class="p">,</span><span class="w"> </span><span class="p">...);</span>
</span></code></pre></div>
<h4 id="prevention_1">Prevention<a class="headerlink" href="#prevention_1" title="Permanent link">&para;</a></h4>
<ul>
<li><strong>Role-based access control</strong> - Clear role hierarchy</li>
<li><strong>Explicit permissions</strong> - Each endpoint lists required roles</li>
<li><strong>Audit trail</strong> - Track permission changes</li>
<li><strong>Documentation</strong> - Role matrix in <a href="../technical/api-reference.md#access-control">Access Control</a></li>
</ul>
<hr />
<h3 id="invalid-token">Invalid Token<a class="headerlink" href="#invalid-token" title="Permanent link">&para;</a></h3>
<p><strong>Severity:</strong> 🟠 High</p>
<h4 id="symptoms_2">Symptoms<a class="headerlink" href="#symptoms_2" title="Permanent link">&para;</a></h4>
<div class="language-json highlight"><pre><span></span><code><span id="__span-12-1"><a id="__codelineno-12-1" name="__codelineno-12-1" href="#__codelineno-12-1"></a><span class="p">{</span>
</span><span id="__span-12-2"><a id="__codelineno-12-2" name="__codelineno-12-2" href="#__codelineno-12-2"></a><span class="w"> </span><span class="nt">&quot;error&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Unauthorized&quot;</span><span class="p">,</span>
</span><span id="__span-12-3"><a id="__codelineno-12-3" name="__codelineno-12-3" href="#__codelineno-12-3"></a><span class="w"> </span><span class="nt">&quot;message&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Invalid token&quot;</span>
</span><span id="__span-12-4"><a id="__codelineno-12-4" name="__codelineno-12-4" href="#__codelineno-12-4"></a><span class="p">}</span>
</span></code></pre></div>
<p>Or in API logs:
<div class="language-text highlight"><pre><span></span><code><span id="__span-13-1"><a id="__codelineno-13-1" name="__codelineno-13-1" href="#__codelineno-13-1"></a>Error: jwt malformed
</span><span id="__span-13-2"><a id="__codelineno-13-2" name="__codelineno-13-2" href="#__codelineno-13-2"></a>Error: invalid signature
</span><span id="__span-13-3"><a id="__codelineno-13-3" name="__codelineno-13-3" href="#__codelineno-13-3"></a>Error: jwt must be provided
</span></code></pre></div></p>
<h4 id="common-causes_2">Common Causes<a class="headerlink" href="#common-causes_2" title="Permanent link">&para;</a></h4>
<ol>
<li><strong>Corrupted token</strong> - LocalStorage corruption</li>
<li><strong>Wrong secret</strong> - JWT_ACCESS_SECRET changed</li>
<li><strong>Modified token</strong> - Attempted tampering</li>
<li><strong>Format error</strong> - Not a valid JWT structure</li>
</ol>
<h4 id="solutions_2">Solutions<a class="headerlink" href="#solutions_2" title="Permanent link">&para;</a></h4>
<p><strong>Solution 1: Clear and re-login</strong></p>
<div class="language-javascript highlight"><pre><span></span><code><span id="__span-14-1"><a id="__codelineno-14-1" name="__codelineno-14-1" href="#__codelineno-14-1"></a><span class="c1">// In browser console</span>
</span><span id="__span-14-2"><a id="__codelineno-14-2" name="__codelineno-14-2" href="#__codelineno-14-2"></a><span class="nx">localStorage</span><span class="p">.</span><span class="nx">clear</span><span class="p">();</span>
</span><span id="__span-14-3"><a id="__codelineno-14-3" name="__codelineno-14-3" href="#__codelineno-14-3"></a><span class="c1">// Then log in again</span>
</span></code></pre></div>
<p><strong>Solution 2: Verify JWT structure</strong></p>
<p>Valid JWT has 3 parts separated by dots:</p>
<div class="language-javascript highlight"><pre><span></span><code><span id="__span-15-1"><a id="__codelineno-15-1" name="__codelineno-15-1" href="#__codelineno-15-1"></a><span class="kd">const</span><span class="w"> </span><span class="nx">token</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;header.payload.signature&#39;</span><span class="p">;</span>
</span><span id="__span-15-2"><a id="__codelineno-15-2" name="__codelineno-15-2" href="#__codelineno-15-2"></a><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">token</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">&#39;.&#39;</span><span class="p">).</span><span class="nx">length</span><span class="p">);</span><span class="w"> </span><span class="c1">// Should be 3</span>
</span></code></pre></div>
<p><strong>Solution 3: Check secret configuration</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-16-1"><a id="__codelineno-16-1" name="__codelineno-16-1" href="#__codelineno-16-1"></a><span class="c1"># In .env</span>
</span><span id="__span-16-2"><a id="__codelineno-16-2" name="__codelineno-16-2" href="#__codelineno-16-2"></a><span class="nv">JWT_ACCESS_SECRET</span><span class="o">=</span>your-secret-here-32-chars-min
</span><span id="__span-16-3"><a id="__codelineno-16-3" name="__codelineno-16-3" href="#__codelineno-16-3"></a><span class="nv">JWT_REFRESH_SECRET</span><span class="o">=</span>different-secret-here-32-chars-min
</span><span id="__span-16-4"><a id="__codelineno-16-4" name="__codelineno-16-4" href="#__codelineno-16-4"></a>
</span><span id="__span-16-5"><a id="__codelineno-16-5" name="__codelineno-16-5" href="#__codelineno-16-5"></a><span class="c1"># Secrets must:</span>
</span><span id="__span-16-6"><a id="__codelineno-16-6" name="__codelineno-16-6" href="#__codelineno-16-6"></a><span class="c1"># - Be different from each other</span>
</span><span id="__span-16-7"><a id="__codelineno-16-7" name="__codelineno-16-7" href="#__codelineno-16-7"></a><span class="c1"># - Be at least 32 characters</span>
</span><span id="__span-16-8"><a id="__codelineno-16-8" name="__codelineno-16-8" href="#__codelineno-16-8"></a><span class="c1"># - Remain unchanged (changing invalidates all tokens)</span>
</span></code></pre></div>
<p><strong>Solution 4: Verify token in logs</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-17-1"><a id="__codelineno-17-1" name="__codelineno-17-1" href="#__codelineno-17-1"></a><span class="c1"># API logs show token validation errors</span>
</span><span id="__span-17-2"><a id="__codelineno-17-2" name="__codelineno-17-2" href="#__codelineno-17-2"></a>docker<span class="w"> </span>compose<span class="w"> </span>logs<span class="w"> </span>api<span class="w"> </span><span class="p">|</span><span class="w"> </span>tail<span class="w"> </span>-100<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span><span class="s2">&quot;jwt&quot;</span>
</span></code></pre></div>
<h4 id="prevention_2">Prevention<a class="headerlink" href="#prevention_2" title="Permanent link">&para;</a></h4>
<ul>
<li><strong>Secure secrets</strong> - Use <code>openssl rand -hex 32</code></li>
<li><strong>Never commit secrets</strong> - Keep in .env (gitignored)</li>
<li><strong>Rotate carefully</strong> - Changing secrets logs out all users</li>
<li><strong>Monitor errors</strong> - Alert on spike in invalid token errors</li>
</ul>
<hr />
<h3 id="token-expired">Token Expired<a class="headerlink" href="#token-expired" title="Permanent link">&para;</a></h3>
<p><strong>Severity:</strong> 🟡 Medium</p>
<h4 id="symptoms_3">Symptoms<a class="headerlink" href="#symptoms_3" title="Permanent link">&para;</a></h4>
<div class="language-json highlight"><pre><span></span><code><span id="__span-18-1"><a id="__codelineno-18-1" name="__codelineno-18-1" href="#__codelineno-18-1"></a><span class="p">{</span>
</span><span id="__span-18-2"><a id="__codelineno-18-2" name="__codelineno-18-2" href="#__codelineno-18-2"></a><span class="w"> </span><span class="nt">&quot;error&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Unauthorized&quot;</span><span class="p">,</span>
</span><span id="__span-18-3"><a id="__codelineno-18-3" name="__codelineno-18-3" href="#__codelineno-18-3"></a><span class="w"> </span><span class="nt">&quot;message&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Token expired&quot;</span>
</span><span id="__span-18-4"><a id="__codelineno-18-4" name="__codelineno-18-4" href="#__codelineno-18-4"></a><span class="p">}</span>
</span></code></pre></div>
<p>Or:
<div class="language-text highlight"><pre><span></span><code><span id="__span-19-1"><a id="__codelineno-19-1" name="__codelineno-19-1" href="#__codelineno-19-1"></a>Error: jwt expired
</span></code></pre></div></p>
<h4 id="common-causes_3">Common Causes<a class="headerlink" href="#common-causes_3" title="Permanent link">&para;</a></h4>
<ol>
<li><strong>Access token expired</strong> - Normal after 15 minutes of inactivity</li>
<li><strong>Refresh token expired</strong> - Refresh token older than 7 days</li>
<li><strong>System clock skew</strong> - Server/client time mismatch</li>
<li><strong>Refresh failed</strong> - Refresh token invalid or revoked</li>
</ol>
<h4 id="solutions_3">Solutions<a class="headerlink" href="#solutions_3" title="Permanent link">&para;</a></h4>
<p><strong>Solution 1: Automatic refresh</strong></p>
<p>Frontend automatically refreshes tokens on 401. If this fails:</p>
<div class="language-javascript highlight"><pre><span></span><code><span id="__span-20-1"><a id="__codelineno-20-1" name="__codelineno-20-1" href="#__codelineno-20-1"></a><span class="c1">// Check refresh token in localStorage</span>
</span><span id="__span-20-2"><a id="__codelineno-20-2" name="__codelineno-20-2" href="#__codelineno-20-2"></a><span class="kd">const</span><span class="w"> </span><span class="nx">storage</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">localStorage</span><span class="p">.</span><span class="nx">getItem</span><span class="p">(</span><span class="s1">&#39;auth-storage&#39;</span><span class="p">));</span>
</span><span id="__span-20-3"><a id="__codelineno-20-3" name="__codelineno-20-3" href="#__codelineno-20-3"></a><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;Has refresh token:&#39;</span><span class="p">,</span><span class="w"> </span><span class="o">!!</span><span class="nx">storage</span><span class="o">?</span><span class="p">.</span><span class="nx">state</span><span class="o">?</span><span class="p">.</span><span class="nx">refreshToken</span><span class="p">);</span>
</span></code></pre></div>
<p><strong>Solution 2: Manual login</strong></p>
<p>If refresh token expired (after 7 days):</p>
<ol>
<li>You'll be redirected to login automatically</li>
<li>Log in with email/password</li>
<li>New tokens issued</li>
</ol>
<p><strong>Solution 3: Check system time</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-21-1"><a id="__codelineno-21-1" name="__codelineno-21-1" href="#__codelineno-21-1"></a><span class="c1"># On server</span>
</span><span id="__span-21-2"><a id="__codelineno-21-2" name="__codelineno-21-2" href="#__codelineno-21-2"></a>date
</span><span id="__span-21-3"><a id="__codelineno-21-3" name="__codelineno-21-3" href="#__codelineno-21-3"></a>
</span><span id="__span-21-4"><a id="__codelineno-21-4" name="__codelineno-21-4" href="#__codelineno-21-4"></a><span class="c1"># Sync if incorrect</span>
</span><span id="__span-21-5"><a id="__codelineno-21-5" name="__codelineno-21-5" href="#__codelineno-21-5"></a>sudo<span class="w"> </span>ntpdate<span class="w"> </span>-s<span class="w"> </span>time.nist.gov
</span></code></pre></div>
<p><strong>Solution 4: Verify token expiration</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-22-1"><a id="__codelineno-22-1" name="__codelineno-22-1" href="#__codelineno-22-1"></a><span class="c1"># In API logs</span>
</span><span id="__span-22-2"><a id="__codelineno-22-2" name="__codelineno-22-2" href="#__codelineno-22-2"></a>docker<span class="w"> </span>compose<span class="w"> </span>logs<span class="w"> </span>api<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span><span class="s2">&quot;expired&quot;</span>
</span><span id="__span-22-3"><a id="__codelineno-22-3" name="__codelineno-22-3" href="#__codelineno-22-3"></a>
</span><span id="__span-22-4"><a id="__codelineno-22-4" name="__codelineno-22-4" href="#__codelineno-22-4"></a><span class="c1"># Check token age</span>
</span><span id="__span-22-5"><a id="__codelineno-22-5" name="__codelineno-22-5" href="#__codelineno-22-5"></a>docker<span class="w"> </span>compose<span class="w"> </span><span class="nb">exec</span><span class="w"> </span>v2-postgres<span class="w"> </span>psql<span class="w"> </span>-U<span class="w"> </span>changemaker<span class="w"> </span>-d<span class="w"> </span>changemaker_v2<span class="w"> </span><span class="se">\</span>
</span><span id="__span-22-6"><a id="__codelineno-22-6" name="__codelineno-22-6" href="#__codelineno-22-6"></a><span class="w"> </span>-c<span class="w"> </span><span class="s2">&quot;SELECT email, \&quot;createdAt\&quot;, \&quot;expiresAt\&quot; FROM \&quot;RefreshToken\&quot; ORDER BY \&quot;createdAt\&quot; DESC LIMIT 10;&quot;</span>
</span></code></pre></div>
<h4 id="prevention_3">Prevention<a class="headerlink" href="#prevention_3" title="Permanent link">&para;</a></h4>
<ul>
<li><strong>Sliding sessions</strong> - Tokens auto-refresh on activity</li>
<li><strong>Long refresh window</strong> - 7-day refresh token validity</li>
<li><strong>Graceful handling</strong> - Automatic re-login redirect</li>
<li><strong>Activity tracking</strong> - Monitor token refresh patterns</li>
</ul>
<div class="admonition tip">
<p class="admonition-title">Developer Tip</p>
<p>During development, use longer token expiration in .env:
<div class="language-bash highlight"><pre><span></span><code><span id="__span-23-1"><a id="__codelineno-23-1" name="__codelineno-23-1" href="#__codelineno-23-1"></a><span class="nv">JWT_ACCESS_EXPIRATION</span><span class="o">=</span>1d<span class="w"> </span><span class="c1"># Instead of 15m</span>
</span><span id="__span-23-2"><a id="__codelineno-23-2" name="__codelineno-23-2" href="#__codelineno-23-2"></a><span class="nv">JWT_REFRESH_EXPIRATION</span><span class="o">=</span>30d<span class="w"> </span><span class="c1"># Instead of 7d</span>
</span></code></pre></div></p>
</div>
<hr />
<h3 id="user-not-found">User Not Found<a class="headerlink" href="#user-not-found" title="Permanent link">&para;</a></h3>
<p><strong>Severity:</strong> 🟡 Medium</p>
<h4 id="symptoms_4">Symptoms<a class="headerlink" href="#symptoms_4" title="Permanent link">&para;</a></h4>
<div class="language-json highlight"><pre><span></span><code><span id="__span-24-1"><a id="__codelineno-24-1" name="__codelineno-24-1" href="#__codelineno-24-1"></a><span class="p">{</span>
</span><span id="__span-24-2"><a id="__codelineno-24-2" name="__codelineno-24-2" href="#__codelineno-24-2"></a><span class="w"> </span><span class="nt">&quot;error&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Unauthorized&quot;</span><span class="p">,</span>
</span><span id="__span-24-3"><a id="__codelineno-24-3" name="__codelineno-24-3" href="#__codelineno-24-3"></a><span class="w"> </span><span class="nt">&quot;message&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Invalid credentials&quot;</span>
</span><span id="__span-24-4"><a id="__codelineno-24-4" name="__codelineno-24-4" href="#__codelineno-24-4"></a><span class="p">}</span>
</span></code></pre></div>
<p>Note: Same message for both "user not found" and "wrong password" (security feature).</p>
<h4 id="common-causes_4">Common Causes<a class="headerlink" href="#common-causes_4" title="Permanent link">&para;</a></h4>
<ol>
<li><strong>Wrong email</strong> - Typo in email address</li>
<li><strong>User deleted</strong> - Account removed from database</li>
<li><strong>Wrong database</strong> - Connected to wrong environment</li>
<li><strong>Case sensitivity</strong> - Email stored differently</li>
</ol>
<h4 id="solutions_4">Solutions<a class="headerlink" href="#solutions_4" title="Permanent link">&para;</a></h4>
<p><strong>Solution 1: Verify user exists</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-25-1"><a id="__codelineno-25-1" name="__codelineno-25-1" href="#__codelineno-25-1"></a><span class="c1"># Check database</span>
</span><span id="__span-25-2"><a id="__codelineno-25-2" name="__codelineno-25-2" href="#__codelineno-25-2"></a>docker<span class="w"> </span>compose<span class="w"> </span><span class="nb">exec</span><span class="w"> </span>v2-postgres<span class="w"> </span>psql<span class="w"> </span>-U<span class="w"> </span>changemaker<span class="w"> </span>-d<span class="w"> </span>changemaker_v2<span class="w"> </span><span class="se">\</span>
</span><span id="__span-25-3"><a id="__codelineno-25-3" name="__codelineno-25-3" href="#__codelineno-25-3"></a><span class="w"> </span>-c<span class="w"> </span><span class="s2">&quot;SELECT email, role FROM \&quot;User\&quot; WHERE email ILIKE &#39;%search%&#39;;&quot;</span>
</span></code></pre></div>
<p><strong>Solution 2: Check email format</strong></p>
<p>Emails are stored lowercase:</p>
<div class="language-sql highlight"><pre><span></span><code><span id="__span-26-1"><a id="__codelineno-26-1" name="__codelineno-26-1" href="#__codelineno-26-1"></a><span class="c1">-- Find user case-insensitive</span>
</span><span id="__span-26-2"><a id="__codelineno-26-2" name="__codelineno-26-2" href="#__codelineno-26-2"></a><span class="k">SELECT</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="ss">&quot;User&quot;</span><span class="w"> </span><span class="k">WHERE</span><span class="w"> </span><span class="k">LOWER</span><span class="p">(</span><span class="n">email</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">LOWER</span><span class="p">(</span><span class="s1">&#39;User@Example.com&#39;</span><span class="p">);</span>
</span></code></pre></div>
<p><strong>Solution 3: Create user if missing</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-27-1"><a id="__codelineno-27-1" name="__codelineno-27-1" href="#__codelineno-27-1"></a><span class="c1"># Via API</span>
</span><span id="__span-27-2"><a id="__codelineno-27-2" name="__codelineno-27-2" href="#__codelineno-27-2"></a>curl<span class="w"> </span>-X<span class="w"> </span>POST<span class="w"> </span>http://localhost:4000/api/auth/register<span class="w"> </span><span class="se">\</span>
</span><span id="__span-27-3"><a id="__codelineno-27-3" name="__codelineno-27-3" href="#__codelineno-27-3"></a><span class="w"> </span>-H<span class="w"> </span><span class="s2">&quot;Content-Type: application/json&quot;</span><span class="w"> </span><span class="se">\</span>
</span><span id="__span-27-4"><a id="__codelineno-27-4" name="__codelineno-27-4" href="#__codelineno-27-4"></a><span class="w"> </span>-d<span class="w"> </span><span class="s1">&#39;{</span>
</span><span id="__span-27-5"><a id="__codelineno-27-5" name="__codelineno-27-5" href="#__codelineno-27-5"></a><span class="s1"> &quot;email&quot;: &quot;user@example.com&quot;,</span>
</span><span id="__span-27-6"><a id="__codelineno-27-6" name="__codelineno-27-6" href="#__codelineno-27-6"></a><span class="s1"> &quot;password&quot;: &quot;SecurePass123!&quot;,</span>
</span><span id="__span-27-7"><a id="__codelineno-27-7" name="__codelineno-27-7" href="#__codelineno-27-7"></a><span class="s1"> &quot;name&quot;: &quot;User Name&quot;</span>
</span><span id="__span-27-8"><a id="__codelineno-27-8" name="__codelineno-27-8" href="#__codelineno-27-8"></a><span class="s1"> }&#39;</span>
</span><span id="__span-27-9"><a id="__codelineno-27-9" name="__codelineno-27-9" href="#__codelineno-27-9"></a>
</span><span id="__span-27-10"><a id="__codelineno-27-10" name="__codelineno-27-10" href="#__codelineno-27-10"></a><span class="c1"># Or via admin UI at /app/users</span>
</span></code></pre></div>
<p><strong>Solution 4: Check database connection</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-28-1"><a id="__codelineno-28-1" name="__codelineno-28-1" href="#__codelineno-28-1"></a><span class="c1"># Verify correct database</span>
</span><span id="__span-28-2"><a id="__codelineno-28-2" name="__codelineno-28-2" href="#__codelineno-28-2"></a>docker<span class="w"> </span>compose<span class="w"> </span><span class="nb">exec</span><span class="w"> </span>api<span class="w"> </span>npx<span class="w"> </span>prisma<span class="w"> </span>db<span class="w"> </span>pull
</span><span id="__span-28-3"><a id="__codelineno-28-3" name="__codelineno-28-3" href="#__codelineno-28-3"></a>
</span><span id="__span-28-4"><a id="__codelineno-28-4" name="__codelineno-28-4" href="#__codelineno-28-4"></a><span class="c1"># Check DATABASE_URL in .env</span>
</span><span id="__span-28-5"><a id="__codelineno-28-5" name="__codelineno-28-5" href="#__codelineno-28-5"></a>cat<span class="w"> </span>.env<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>DATABASE_URL
</span></code></pre></div>
<h4 id="prevention_4">Prevention<a class="headerlink" href="#prevention_4" title="Permanent link">&para;</a></h4>
<ul>
<li><strong>Email validation</strong> - Enforce valid email format</li>
<li><strong>Case normalization</strong> - Store emails lowercase</li>
<li><strong>Soft deletes</strong> - Consider flagging instead of deleting</li>
<li><strong>Audit trail</strong> - Log user deletions</li>
</ul>
<hr />
<h2 id="api-errors">API Errors<a class="headerlink" href="#api-errors" title="Permanent link">&para;</a></h2>
<h3 id="500-internal-server-error">500 Internal Server Error<a class="headerlink" href="#500-internal-server-error" title="Permanent link">&para;</a></h3>
<p><strong>Severity:</strong> 🔴 Critical</p>
<h4 id="symptoms_5">Symptoms<a class="headerlink" href="#symptoms_5" title="Permanent link">&para;</a></h4>
<div class="language-json highlight"><pre><span></span><code><span id="__span-29-1"><a id="__codelineno-29-1" name="__codelineno-29-1" href="#__codelineno-29-1"></a><span class="p">{</span>
</span><span id="__span-29-2"><a id="__codelineno-29-2" name="__codelineno-29-2" href="#__codelineno-29-2"></a><span class="w"> </span><span class="nt">&quot;error&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Internal Server Error&quot;</span><span class="p">,</span>
</span><span id="__span-29-3"><a id="__codelineno-29-3" name="__codelineno-29-3" href="#__codelineno-29-3"></a><span class="w"> </span><span class="nt">&quot;message&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;An unexpected error occurred&quot;</span>
</span><span id="__span-29-4"><a id="__codelineno-29-4" name="__codelineno-29-4" href="#__codelineno-29-4"></a><span class="p">}</span>
</span></code></pre></div>
<p>Or frontend error:
<div class="language-text highlight"><pre><span></span><code><span id="__span-30-1"><a id="__codelineno-30-1" name="__codelineno-30-1" href="#__codelineno-30-1"></a>Error: Request failed with status code 500
</span></code></pre></div></p>
<h4 id="common-causes_5">Common Causes<a class="headerlink" href="#common-causes_5" title="Permanent link">&para;</a></h4>
<ol>
<li><strong>Unhandled exception</strong> - Code threw unexpected error</li>
<li><strong>Database error</strong> - Query failed</li>
<li><strong>Missing environment variable</strong> - Required config missing</li>
<li><strong>Type error</strong> - Runtime type mismatch</li>
</ol>
<h4 id="solutions_5">Solutions<a class="headerlink" href="#solutions_5" title="Permanent link">&para;</a></h4>
<p><strong>Solution 1: Check API logs</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-31-1"><a id="__codelineno-31-1" name="__codelineno-31-1" href="#__codelineno-31-1"></a><span class="c1"># View recent logs</span>
</span><span id="__span-31-2"><a id="__codelineno-31-2" name="__codelineno-31-2" href="#__codelineno-31-2"></a>docker<span class="w"> </span>compose<span class="w"> </span>logs<span class="w"> </span>api<span class="w"> </span>--tail<span class="o">=</span><span class="m">100</span>
</span><span id="__span-31-3"><a id="__codelineno-31-3" name="__codelineno-31-3" href="#__codelineno-31-3"></a>
</span><span id="__span-31-4"><a id="__codelineno-31-4" name="__codelineno-31-4" href="#__codelineno-31-4"></a><span class="c1"># Follow logs in real-time</span>
</span><span id="__span-31-5"><a id="__codelineno-31-5" name="__codelineno-31-5" href="#__codelineno-31-5"></a>docker<span class="w"> </span>compose<span class="w"> </span>logs<span class="w"> </span>-f<span class="w"> </span>api
</span><span id="__span-31-6"><a id="__codelineno-31-6" name="__codelineno-31-6" href="#__codelineno-31-6"></a>
</span><span id="__span-31-7"><a id="__codelineno-31-7" name="__codelineno-31-7" href="#__codelineno-31-7"></a><span class="c1"># Search for errors</span>
</span><span id="__span-31-8"><a id="__codelineno-31-8" name="__codelineno-31-8" href="#__codelineno-31-8"></a>docker<span class="w"> </span>compose<span class="w"> </span>logs<span class="w"> </span>api<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>-i<span class="w"> </span>error<span class="w"> </span><span class="p">|</span><span class="w"> </span>tail<span class="w"> </span>-20
</span></code></pre></div>
<p><strong>Solution 2: Common error patterns</strong></p>
<div class="language-javascript highlight"><pre><span></span><code><span id="__span-32-1"><a id="__codelineno-32-1" name="__codelineno-32-1" href="#__codelineno-32-1"></a><span class="c1">// Missing environment variable</span>
</span><span id="__span-32-2"><a id="__codelineno-32-2" name="__codelineno-32-2" href="#__codelineno-32-2"></a><span class="ne">Error</span><span class="o">:</span><span class="w"> </span><span class="nx">SMTP_HOST</span><span class="w"> </span><span class="nx">is</span><span class="w"> </span><span class="nx">required</span>
</span><span id="__span-32-3"><a id="__codelineno-32-3" name="__codelineno-32-3" href="#__codelineno-32-3"></a><span class="c1">// Solution: Add to .env</span>
</span><span id="__span-32-4"><a id="__codelineno-32-4" name="__codelineno-32-4" href="#__codelineno-32-4"></a>
</span><span id="__span-32-5"><a id="__codelineno-32-5" name="__codelineno-32-5" href="#__codelineno-32-5"></a><span class="c1">// Database connection error</span>
</span><span id="__span-32-6"><a id="__codelineno-32-6" name="__codelineno-32-6" href="#__codelineno-32-6"></a><span class="ne">Error</span><span class="o">:</span><span class="w"> </span><span class="nx">Can</span><span class="s1">&#39;t reach database server at `v2-postgres:5432`</span>
</span><span id="__span-32-7"><a id="__codelineno-32-7" name="__codelineno-32-7" href="#__codelineno-32-7"></a><span class="s1">// Solution: Check database is running</span>
</span><span id="__span-32-8"><a id="__codelineno-32-8" name="__codelineno-32-8" href="#__codelineno-32-8"></a>
</span><span id="__span-32-9"><a id="__codelineno-32-9" name="__codelineno-32-9" href="#__codelineno-32-9"></a><span class="s1">// Type error</span>
</span><span id="__span-32-10"><a id="__codelineno-32-10" name="__codelineno-32-10" href="#__codelineno-32-10"></a><span class="s1">TypeError: Cannot read property &#39;</span><span class="nx">id</span><span class="err">&#39;</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="kc">undefined</span>
</span><span id="__span-32-11"><a id="__codelineno-32-11" name="__codelineno-32-11" href="#__codelineno-32-11"></a><span class="c1">// Solution: Check code for null checks</span>
</span></code></pre></div>
<p><strong>Solution 3: Restart API</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-33-1"><a id="__codelineno-33-1" name="__codelineno-33-1" href="#__codelineno-33-1"></a><span class="c1"># Restart API container</span>
</span><span id="__span-33-2"><a id="__codelineno-33-2" name="__codelineno-33-2" href="#__codelineno-33-2"></a>docker<span class="w"> </span>compose<span class="w"> </span>restart<span class="w"> </span>api
</span><span id="__span-33-3"><a id="__codelineno-33-3" name="__codelineno-33-3" href="#__codelineno-33-3"></a>
</span><span id="__span-33-4"><a id="__codelineno-33-4" name="__codelineno-33-4" href="#__codelineno-33-4"></a><span class="c1"># Or rebuild if code changed</span>
</span><span id="__span-33-5"><a id="__codelineno-33-5" name="__codelineno-33-5" href="#__codelineno-33-5"></a>docker<span class="w"> </span>compose<span class="w"> </span>up<span class="w"> </span>-d<span class="w"> </span>--build<span class="w"> </span>api
</span></code></pre></div>
<p><strong>Solution 4: Enable debug logging</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-34-1"><a id="__codelineno-34-1" name="__codelineno-34-1" href="#__codelineno-34-1"></a><span class="c1"># In .env</span>
</span><span id="__span-34-2"><a id="__codelineno-34-2" name="__codelineno-34-2" href="#__codelineno-34-2"></a><span class="nv">LOG_LEVEL</span><span class="o">=</span>debug
</span><span id="__span-34-3"><a id="__codelineno-34-3" name="__codelineno-34-3" href="#__codelineno-34-3"></a>
</span><span id="__span-34-4"><a id="__codelineno-34-4" name="__codelineno-34-4" href="#__codelineno-34-4"></a><span class="c1"># Restart API</span>
</span><span id="__span-34-5"><a id="__codelineno-34-5" name="__codelineno-34-5" href="#__codelineno-34-5"></a>docker<span class="w"> </span>compose<span class="w"> </span>restart<span class="w"> </span>api
</span><span id="__span-34-6"><a id="__codelineno-34-6" name="__codelineno-34-6" href="#__codelineno-34-6"></a>
</span><span id="__span-34-7"><a id="__codelineno-34-7" name="__codelineno-34-7" href="#__codelineno-34-7"></a><span class="c1"># Check detailed logs</span>
</span><span id="__span-34-8"><a id="__codelineno-34-8" name="__codelineno-34-8" href="#__codelineno-34-8"></a>docker<span class="w"> </span>compose<span class="w"> </span>logs<span class="w"> </span>api
</span></code></pre></div>
<h4 id="prevention_5">Prevention<a class="headerlink" href="#prevention_5" title="Permanent link">&para;</a></h4>
<ul>
<li><strong>Error handling</strong> - Try/catch in all routes</li>
<li><strong>Input validation</strong> - Validate all inputs with Zod</li>
<li><strong>Type safety</strong> - Use TypeScript strictly</li>
<li><strong>Health checks</strong> - Monitor API health</li>
<li><strong>Alerting</strong> - Set up alerts for 500 errors</li>
</ul>
<div class="admonition warning">
<p class="admonition-title">Production Alert</p>
<p>500 errors indicate bugs. Always investigate and fix root cause.</p>
</div>
<hr />
<h3 id="400-bad-request">400 Bad Request<a class="headerlink" href="#400-bad-request" title="Permanent link">&para;</a></h3>
<p><strong>Severity:</strong> 🟡 Medium</p>
<h4 id="symptoms_6">Symptoms<a class="headerlink" href="#symptoms_6" title="Permanent link">&para;</a></h4>
<div class="language-json highlight"><pre><span></span><code><span id="__span-35-1"><a id="__codelineno-35-1" name="__codelineno-35-1" href="#__codelineno-35-1"></a><span class="p">{</span>
</span><span id="__span-35-2"><a id="__codelineno-35-2" name="__codelineno-35-2" href="#__codelineno-35-2"></a><span class="w"> </span><span class="nt">&quot;error&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Bad Request&quot;</span><span class="p">,</span>
</span><span id="__span-35-3"><a id="__codelineno-35-3" name="__codelineno-35-3" href="#__codelineno-35-3"></a><span class="w"> </span><span class="nt">&quot;message&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Invalid request format&quot;</span>
</span><span id="__span-35-4"><a id="__codelineno-35-4" name="__codelineno-35-4" href="#__codelineno-35-4"></a><span class="p">}</span>
</span></code></pre></div>
<p>Or with validation details:
<div class="language-json highlight"><pre><span></span><code><span id="__span-36-1"><a id="__codelineno-36-1" name="__codelineno-36-1" href="#__codelineno-36-1"></a><span class="p">{</span>
</span><span id="__span-36-2"><a id="__codelineno-36-2" name="__codelineno-36-2" href="#__codelineno-36-2"></a><span class="w"> </span><span class="nt">&quot;error&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Bad Request&quot;</span><span class="p">,</span>
</span><span id="__span-36-3"><a id="__codelineno-36-3" name="__codelineno-36-3" href="#__codelineno-36-3"></a><span class="w"> </span><span class="nt">&quot;message&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Validation failed: 2 errors&quot;</span>
</span><span id="__span-36-4"><a id="__codelineno-36-4" name="__codelineno-36-4" href="#__codelineno-36-4"></a><span class="p">}</span>
</span></code></pre></div></p>
<h4 id="common-causes_6">Common Causes<a class="headerlink" href="#common-causes_6" title="Permanent link">&para;</a></h4>
<ol>
<li><strong>Invalid JSON</strong> - Malformed request body</li>
<li><strong>Wrong Content-Type</strong> - Missing or incorrect header</li>
<li><strong>Missing required field</strong> - Required parameter not sent</li>
<li><strong>Invalid data type</strong> - String sent for number field</li>
</ol>
<h4 id="solutions_6">Solutions<a class="headerlink" href="#solutions_6" title="Permanent link">&para;</a></h4>
<p><strong>Solution 1: Check request format</strong></p>
<div class="language-javascript highlight"><pre><span></span><code><span id="__span-37-1"><a id="__codelineno-37-1" name="__codelineno-37-1" href="#__codelineno-37-1"></a><span class="c1">// Correct format</span>
</span><span id="__span-37-2"><a id="__codelineno-37-2" name="__codelineno-37-2" href="#__codelineno-37-2"></a><span class="kd">const</span><span class="w"> </span><span class="nx">response</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">api</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="s1">&#39;/api/users&#39;</span><span class="p">,</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-37-3"><a id="__codelineno-37-3" name="__codelineno-37-3" href="#__codelineno-37-3"></a><span class="w"> </span><span class="nx">email</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;user@example.com&#39;</span><span class="p">,</span>
</span><span id="__span-37-4"><a id="__codelineno-37-4" name="__codelineno-37-4" href="#__codelineno-37-4"></a><span class="w"> </span><span class="nx">password</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;SecurePass123!&#39;</span><span class="p">,</span>
</span><span id="__span-37-5"><a id="__codelineno-37-5" name="__codelineno-37-5" href="#__codelineno-37-5"></a><span class="w"> </span><span class="nx">name</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;User Name&#39;</span>
</span><span id="__span-37-6"><a id="__codelineno-37-6" name="__codelineno-37-6" href="#__codelineno-37-6"></a><span class="p">},</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-37-7"><a id="__codelineno-37-7" name="__codelineno-37-7" href="#__codelineno-37-7"></a><span class="w"> </span><span class="nx">headers</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-37-8"><a id="__codelineno-37-8" name="__codelineno-37-8" href="#__codelineno-37-8"></a><span class="w"> </span><span class="s1">&#39;Content-Type&#39;</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;application/json&#39;</span>
</span><span id="__span-37-9"><a id="__codelineno-37-9" name="__codelineno-37-9" href="#__codelineno-37-9"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-37-10"><a id="__codelineno-37-10" name="__codelineno-37-10" href="#__codelineno-37-10"></a><span class="p">});</span>
</span><span id="__span-37-11"><a id="__codelineno-37-11" name="__codelineno-37-11" href="#__codelineno-37-11"></a>
</span><span id="__span-37-12"><a id="__codelineno-37-12" name="__codelineno-37-12" href="#__codelineno-37-12"></a><span class="c1">// Common mistakes:</span>
</span><span id="__span-37-13"><a id="__codelineno-37-13" name="__codelineno-37-13" href="#__codelineno-37-13"></a><span class="c1">// ❌ Missing Content-Type header</span>
</span><span id="__span-37-14"><a id="__codelineno-37-14" name="__codelineno-37-14" href="#__codelineno-37-14"></a><span class="c1">// ❌ Sending FormData to JSON endpoint</span>
</span><span id="__span-37-15"><a id="__codelineno-37-15" name="__codelineno-37-15" href="#__codelineno-37-15"></a><span class="c1">// ❌ Malformed JSON (trailing comma, unquoted keys)</span>
</span></code></pre></div>
<p><strong>Solution 2: Validate against schema</strong></p>
<p>Check API schema in <code>api/src/modules/*/schemas.ts</code>:</p>
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-38-1"><a id="__codelineno-38-1" name="__codelineno-38-1" href="#__codelineno-38-1"></a><span class="c1">// Example: User creation schema</span>
</span><span id="__span-38-2"><a id="__codelineno-38-2" name="__codelineno-38-2" href="#__codelineno-38-2"></a><span class="k">export</span><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">createUserSchema</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">z</span><span class="p">.</span><span class="nx">object</span><span class="p">({</span>
</span><span id="__span-38-3"><a id="__codelineno-38-3" name="__codelineno-38-3" href="#__codelineno-38-3"></a><span class="w"> </span><span class="nx">email</span><span class="o">:</span><span class="w"> </span><span class="kt">z.string</span><span class="p">().</span><span class="nx">email</span><span class="p">(),</span>
</span><span id="__span-38-4"><a id="__codelineno-38-4" name="__codelineno-38-4" href="#__codelineno-38-4"></a><span class="w"> </span><span class="nx">password</span><span class="o">:</span><span class="w"> </span><span class="kt">z.string</span><span class="p">().</span><span class="nx">min</span><span class="p">(</span><span class="mf">12</span><span class="p">),</span>
</span><span id="__span-38-5"><a id="__codelineno-38-5" name="__codelineno-38-5" href="#__codelineno-38-5"></a><span class="w"> </span><span class="nx">name</span><span class="o">:</span><span class="w"> </span><span class="kt">z.string</span><span class="p">().</span><span class="nx">min</span><span class="p">(</span><span class="mf">1</span><span class="p">),</span>
</span><span id="__span-38-6"><a id="__codelineno-38-6" name="__codelineno-38-6" href="#__codelineno-38-6"></a><span class="w"> </span><span class="nx">role</span><span class="o">:</span><span class="w"> </span><span class="kt">z.enum</span><span class="p">([</span><span class="s1">&#39;USER&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;MAP_ADMIN&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;INFLUENCE_ADMIN&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;SUPER_ADMIN&#39;</span><span class="p">]).</span><span class="nx">optional</span><span class="p">()</span>
</span><span id="__span-38-7"><a id="__codelineno-38-7" name="__codelineno-38-7" href="#__codelineno-38-7"></a><span class="p">});</span>
</span></code></pre></div>
<p><strong>Solution 3: Check API logs for details</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-39-1"><a id="__codelineno-39-1" name="__codelineno-39-1" href="#__codelineno-39-1"></a><span class="c1"># Logs show validation errors</span>
</span><span id="__span-39-2"><a id="__codelineno-39-2" name="__codelineno-39-2" href="#__codelineno-39-2"></a>docker<span class="w"> </span>compose<span class="w"> </span>logs<span class="w"> </span>api<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span><span class="s2">&quot;Validation failed&quot;</span>
</span><span id="__span-39-3"><a id="__codelineno-39-3" name="__codelineno-39-3" href="#__codelineno-39-3"></a>
</span><span id="__span-39-4"><a id="__codelineno-39-4" name="__codelineno-39-4" href="#__codelineno-39-4"></a><span class="c1"># Example output:</span>
</span><span id="__span-39-5"><a id="__codelineno-39-5" name="__codelineno-39-5" href="#__codelineno-39-5"></a><span class="c1"># Validation failed: {</span>
</span><span id="__span-39-6"><a id="__codelineno-39-6" name="__codelineno-39-6" href="#__codelineno-39-6"></a><span class="c1"># &quot;email&quot;: &quot;Invalid email format&quot;,</span>
</span><span id="__span-39-7"><a id="__codelineno-39-7" name="__codelineno-39-7" href="#__codelineno-39-7"></a><span class="c1"># &quot;password&quot;: &quot;Must be at least 12 characters&quot;</span>
</span><span id="__span-39-8"><a id="__codelineno-39-8" name="__codelineno-39-8" href="#__codelineno-39-8"></a><span class="c1"># }</span>
</span></code></pre></div>
<p><strong>Solution 4: Test with curl</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-40-1"><a id="__codelineno-40-1" name="__codelineno-40-1" href="#__codelineno-40-1"></a><span class="c1"># Test request</span>
</span><span id="__span-40-2"><a id="__codelineno-40-2" name="__codelineno-40-2" href="#__codelineno-40-2"></a>curl<span class="w"> </span>-X<span class="w"> </span>POST<span class="w"> </span>http://localhost:4000/api/users<span class="w"> </span><span class="se">\</span>
</span><span id="__span-40-3"><a id="__codelineno-40-3" name="__codelineno-40-3" href="#__codelineno-40-3"></a><span class="w"> </span>-H<span class="w"> </span><span class="s2">&quot;Content-Type: application/json&quot;</span><span class="w"> </span><span class="se">\</span>
</span><span id="__span-40-4"><a id="__codelineno-40-4" name="__codelineno-40-4" href="#__codelineno-40-4"></a><span class="w"> </span>-H<span class="w"> </span><span class="s2">&quot;Authorization: Bearer YOUR_TOKEN&quot;</span><span class="w"> </span><span class="se">\</span>
</span><span id="__span-40-5"><a id="__codelineno-40-5" name="__codelineno-40-5" href="#__codelineno-40-5"></a><span class="w"> </span>-d<span class="w"> </span><span class="s1">&#39;{</span>
</span><span id="__span-40-6"><a id="__codelineno-40-6" name="__codelineno-40-6" href="#__codelineno-40-6"></a><span class="s1"> &quot;email&quot;: &quot;test@example.com&quot;,</span>
</span><span id="__span-40-7"><a id="__codelineno-40-7" name="__codelineno-40-7" href="#__codelineno-40-7"></a><span class="s1"> &quot;password&quot;: &quot;SecurePass123!&quot;,</span>
</span><span id="__span-40-8"><a id="__codelineno-40-8" name="__codelineno-40-8" href="#__codelineno-40-8"></a><span class="s1"> &quot;name&quot;: &quot;Test User&quot;</span>
</span><span id="__span-40-9"><a id="__codelineno-40-9" name="__codelineno-40-9" href="#__codelineno-40-9"></a><span class="s1"> }&#39;</span>
</span></code></pre></div>
<h4 id="prevention_6">Prevention<a class="headerlink" href="#prevention_6" title="Permanent link">&para;</a></h4>
<ul>
<li><strong>Client-side validation</strong> - Validate before sending</li>
<li><strong>TypeScript types</strong> - Use generated types from API</li>
<li><strong>Schema documentation</strong> - Document all endpoints</li>
<li><strong>Error messages</strong> - Clear validation error messages</li>
</ul>
<hr />
<h3 id="404-not-found">404 Not Found<a class="headerlink" href="#404-not-found" title="Permanent link">&para;</a></h3>
<p><strong>Severity:</strong> 🟢 Low to 🟡 Medium</p>
<h4 id="symptoms_7">Symptoms<a class="headerlink" href="#symptoms_7" title="Permanent link">&para;</a></h4>
<div class="language-json highlight"><pre><span></span><code><span id="__span-41-1"><a id="__codelineno-41-1" name="__codelineno-41-1" href="#__codelineno-41-1"></a><span class="p">{</span>
</span><span id="__span-41-2"><a id="__codelineno-41-2" name="__codelineno-41-2" href="#__codelineno-41-2"></a><span class="w"> </span><span class="nt">&quot;error&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Not Found&quot;</span><span class="p">,</span>
</span><span id="__span-41-3"><a id="__codelineno-41-3" name="__codelineno-41-3" href="#__codelineno-41-3"></a><span class="w"> </span><span class="nt">&quot;message&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Resource not found&quot;</span>
</span><span id="__span-41-4"><a id="__codelineno-41-4" name="__codelineno-41-4" href="#__codelineno-41-4"></a><span class="p">}</span>
</span></code></pre></div>
<p>Or specific:
<div class="language-json highlight"><pre><span></span><code><span id="__span-42-1"><a id="__codelineno-42-1" name="__codelineno-42-1" href="#__codelineno-42-1"></a><span class="p">{</span>
</span><span id="__span-42-2"><a id="__codelineno-42-2" name="__codelineno-42-2" href="#__codelineno-42-2"></a><span class="w"> </span><span class="nt">&quot;error&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Not Found&quot;</span><span class="p">,</span>
</span><span id="__span-42-3"><a id="__codelineno-42-3" name="__codelineno-42-3" href="#__codelineno-42-3"></a><span class="w"> </span><span class="nt">&quot;message&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Campaign not found&quot;</span>
</span><span id="__span-42-4"><a id="__codelineno-42-4" name="__codelineno-42-4" href="#__codelineno-42-4"></a><span class="p">}</span>
</span></code></pre></div></p>
<h4 id="common-causes_7">Common Causes<a class="headerlink" href="#common-causes_7" title="Permanent link">&para;</a></h4>
<ol>
<li><strong>Wrong ID</strong> - Resource doesn't exist</li>
<li><strong>Wrong URL</strong> - Typo in endpoint path</li>
<li><strong>Deleted resource</strong> - Resource was deleted</li>
<li><strong>Wrong HTTP method</strong> - GET instead of POST</li>
</ol>
<h4 id="solutions_7">Solutions<a class="headerlink" href="#solutions_7" title="Permanent link">&para;</a></h4>
<p><strong>Solution 1: Verify resource exists</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-43-1"><a id="__codelineno-43-1" name="__codelineno-43-1" href="#__codelineno-43-1"></a><span class="c1"># Check database</span>
</span><span id="__span-43-2"><a id="__codelineno-43-2" name="__codelineno-43-2" href="#__codelineno-43-2"></a>docker<span class="w"> </span>compose<span class="w"> </span><span class="nb">exec</span><span class="w"> </span>v2-postgres<span class="w"> </span>psql<span class="w"> </span>-U<span class="w"> </span>changemaker<span class="w"> </span>-d<span class="w"> </span>changemaker_v2<span class="w"> </span><span class="se">\</span>
</span><span id="__span-43-3"><a id="__codelineno-43-3" name="__codelineno-43-3" href="#__codelineno-43-3"></a><span class="w"> </span>-c<span class="w"> </span><span class="s2">&quot;SELECT id, name FROM \&quot;Campaign\&quot; WHERE id = &#39;YOUR_ID&#39;;&quot;</span>
</span></code></pre></div>
<p><strong>Solution 2: Check URL format</strong></p>
<div class="language-javascript highlight"><pre><span></span><code><span id="__span-44-1"><a id="__codelineno-44-1" name="__codelineno-44-1" href="#__codelineno-44-1"></a><span class="c1">// Correct formats</span>
</span><span id="__span-44-2"><a id="__codelineno-44-2" name="__codelineno-44-2" href="#__codelineno-44-2"></a><span class="nx">GET</span><span class="w"> </span><span class="o">/</span><span class="nx">api</span><span class="o">/</span><span class="nx">campaigns</span><span class="o">/:</span><span class="nx">id</span><span class="w"> </span><span class="c1">// Single campaign</span>
</span><span id="__span-44-3"><a id="__codelineno-44-3" name="__codelineno-44-3" href="#__codelineno-44-3"></a><span class="nx">GET</span><span class="w"> </span><span class="o">/</span><span class="nx">api</span><span class="o">/</span><span class="nx">campaigns</span><span class="w"> </span><span class="c1">// List campaigns</span>
</span><span id="__span-44-4"><a id="__codelineno-44-4" name="__codelineno-44-4" href="#__codelineno-44-4"></a><span class="nx">POST</span><span class="w"> </span><span class="o">/</span><span class="nx">api</span><span class="o">/</span><span class="nx">campaigns</span><span class="w"> </span><span class="c1">// Create campaign</span>
</span><span id="__span-44-5"><a id="__codelineno-44-5" name="__codelineno-44-5" href="#__codelineno-44-5"></a><span class="nx">PUT</span><span class="w"> </span><span class="o">/</span><span class="nx">api</span><span class="o">/</span><span class="nx">campaigns</span><span class="o">/:</span><span class="nx">id</span><span class="w"> </span><span class="c1">// Update campaign</span>
</span><span id="__span-44-6"><a id="__codelineno-44-6" name="__codelineno-44-6" href="#__codelineno-44-6"></a><span class="nx">DELETE</span><span class="w"> </span><span class="o">/</span><span class="nx">api</span><span class="o">/</span><span class="nx">campaigns</span><span class="o">/:</span><span class="nx">id</span><span class="w"> </span><span class="c1">// Delete campaign</span>
</span><span id="__span-44-7"><a id="__codelineno-44-7" name="__codelineno-44-7" href="#__codelineno-44-7"></a>
</span><span id="__span-44-8"><a id="__codelineno-44-8" name="__codelineno-44-8" href="#__codelineno-44-8"></a><span class="c1">// Common mistakes:</span>
</span><span id="__span-44-9"><a id="__codelineno-44-9" name="__codelineno-44-9" href="#__codelineno-44-9"></a><span class="c1">// ❌ /api/campaign/:id (singular, should be plural)</span>
</span><span id="__span-44-10"><a id="__codelineno-44-10" name="__codelineno-44-10" href="#__codelineno-44-10"></a><span class="c1">// ❌ /api/campaigns/id/:id (extra &#39;id/&#39; in path)</span>
</span><span id="__span-44-11"><a id="__codelineno-44-11" name="__codelineno-44-11" href="#__codelineno-44-11"></a><span class="c1">// ❌ /api/campaign (wrong singular/plural)</span>
</span></code></pre></div>
<p><strong>Solution 3: Check route registration</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-45-1"><a id="__codelineno-45-1" name="__codelineno-45-1" href="#__codelineno-45-1"></a><span class="c1"># API logs show registered routes on startup</span>
</span><span id="__span-45-2"><a id="__codelineno-45-2" name="__codelineno-45-2" href="#__codelineno-45-2"></a>docker<span class="w"> </span>compose<span class="w"> </span>logs<span class="w"> </span>api<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span><span class="s2">&quot;Registered route&quot;</span>
</span><span id="__span-45-3"><a id="__codelineno-45-3" name="__codelineno-45-3" href="#__codelineno-45-3"></a>
</span><span id="__span-45-4"><a id="__codelineno-45-4" name="__codelineno-45-4" href="#__codelineno-45-4"></a><span class="c1"># Or check routes file</span>
</span><span id="__span-45-5"><a id="__codelineno-45-5" name="__codelineno-45-5" href="#__codelineno-45-5"></a>cat<span class="w"> </span>api/src/modules/*/routes.ts
</span></code></pre></div>
<p><strong>Solution 4: Test endpoint</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-46-1"><a id="__codelineno-46-1" name="__codelineno-46-1" href="#__codelineno-46-1"></a><span class="c1"># List all campaigns to verify endpoint</span>
</span><span id="__span-46-2"><a id="__codelineno-46-2" name="__codelineno-46-2" href="#__codelineno-46-2"></a>curl<span class="w"> </span>http://localhost:4000/api/campaigns
</span><span id="__span-46-3"><a id="__codelineno-46-3" name="__codelineno-46-3" href="#__codelineno-46-3"></a>
</span><span id="__span-46-4"><a id="__codelineno-46-4" name="__codelineno-46-4" href="#__codelineno-46-4"></a><span class="c1"># Test specific ID</span>
</span><span id="__span-46-5"><a id="__codelineno-46-5" name="__codelineno-46-5" href="#__codelineno-46-5"></a>curl<span class="w"> </span>http://localhost:4000/api/campaigns/YOUR_ID
</span></code></pre></div>
<h4 id="prevention_7">Prevention<a class="headerlink" href="#prevention_7" title="Permanent link">&para;</a></h4>
<ul>
<li><strong>UUID validation</strong> - Validate ID format before querying</li>
<li><strong>Soft deletes</strong> - Flag as deleted instead of removing</li>
<li><strong>Resource existence checks</strong> - Verify before operations</li>
<li><strong>Clear error messages</strong> - Specify which resource not found</li>
</ul>
<hr />
<h3 id="422-unprocessable-entity">422 Unprocessable Entity<a class="headerlink" href="#422-unprocessable-entity" title="Permanent link">&para;</a></h3>
<p><strong>Severity:</strong> 🟡 Medium</p>
<h4 id="symptoms_8">Symptoms<a class="headerlink" href="#symptoms_8" title="Permanent link">&para;</a></h4>
<div class="language-json highlight"><pre><span></span><code><span id="__span-47-1"><a id="__codelineno-47-1" name="__codelineno-47-1" href="#__codelineno-47-1"></a><span class="p">{</span>
</span><span id="__span-47-2"><a id="__codelineno-47-2" name="__codelineno-47-2" href="#__codelineno-47-2"></a><span class="w"> </span><span class="nt">&quot;error&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Unprocessable Entity&quot;</span><span class="p">,</span>
</span><span id="__span-47-3"><a id="__codelineno-47-3" name="__codelineno-47-3" href="#__codelineno-47-3"></a><span class="w"> </span><span class="nt">&quot;message&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Validation failed&quot;</span><span class="p">,</span>
</span><span id="__span-47-4"><a id="__codelineno-47-4" name="__codelineno-47-4" href="#__codelineno-47-4"></a><span class="w"> </span><span class="nt">&quot;details&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-47-5"><a id="__codelineno-47-5" name="__codelineno-47-5" href="#__codelineno-47-5"></a><span class="w"> </span><span class="nt">&quot;email&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Email already exists&quot;</span><span class="p">,</span>
</span><span id="__span-47-6"><a id="__codelineno-47-6" name="__codelineno-47-6" href="#__codelineno-47-6"></a><span class="w"> </span><span class="nt">&quot;password&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Must contain uppercase, lowercase, and digit&quot;</span>
</span><span id="__span-47-7"><a id="__codelineno-47-7" name="__codelineno-47-7" href="#__codelineno-47-7"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-47-8"><a id="__codelineno-47-8" name="__codelineno-47-8" href="#__codelineno-47-8"></a><span class="p">}</span>
</span></code></pre></div>
<h4 id="common-causes_8">Common Causes<a class="headerlink" href="#common-causes_8" title="Permanent link">&para;</a></h4>
<ol>
<li><strong>Business logic violation</strong> - Email already exists</li>
<li><strong>Data integrity</strong> - Foreign key doesn't exist</li>
<li><strong>Complex validation</strong> - Password requirements not met</li>
<li><strong>State conflict</strong> - Can't delete resource in use</li>
</ol>
<h4 id="solutions_8">Solutions<a class="headerlink" href="#solutions_8" title="Permanent link">&para;</a></h4>
<p><strong>Solution 1: Read validation details</strong></p>
<p>The <code>details</code> field shows exactly what's wrong:</p>
<div class="language-javascript highlight"><pre><span></span><code><span id="__span-48-1"><a id="__codelineno-48-1" name="__codelineno-48-1" href="#__codelineno-48-1"></a><span class="k">try</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-48-2"><a id="__codelineno-48-2" name="__codelineno-48-2" href="#__codelineno-48-2"></a><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">api</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="s1">&#39;/api/users&#39;</span><span class="p">,</span><span class="w"> </span><span class="nx">userData</span><span class="p">);</span>
</span><span id="__span-48-3"><a id="__codelineno-48-3" name="__codelineno-48-3" href="#__codelineno-48-3"></a><span class="p">}</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="p">(</span><span class="nx">error</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-48-4"><a id="__codelineno-48-4" name="__codelineno-48-4" href="#__codelineno-48-4"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">error</span><span class="p">.</span><span class="nx">response</span><span class="o">?</span><span class="p">.</span><span class="nx">status</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="mf">422</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-48-5"><a id="__codelineno-48-5" name="__codelineno-48-5" href="#__codelineno-48-5"></a><span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;Validation errors:&#39;</span><span class="p">,</span><span class="w"> </span><span class="nx">error</span><span class="p">.</span><span class="nx">response</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">details</span><span class="p">);</span>
</span><span id="__span-48-6"><a id="__codelineno-48-6" name="__codelineno-48-6" href="#__codelineno-48-6"></a><span class="w"> </span><span class="c1">// Show to user field-by-field</span>
</span><span id="__span-48-7"><a id="__codelineno-48-7" name="__codelineno-48-7" href="#__codelineno-48-7"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-48-8"><a id="__codelineno-48-8" name="__codelineno-48-8" href="#__codelineno-48-8"></a><span class="p">}</span>
</span></code></pre></div>
<p><strong>Solution 2: Check constraints</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-49-1"><a id="__codelineno-49-1" name="__codelineno-49-1" href="#__codelineno-49-1"></a><span class="c1"># Email uniqueness</span>
</span><span id="__span-49-2"><a id="__codelineno-49-2" name="__codelineno-49-2" href="#__codelineno-49-2"></a>docker<span class="w"> </span>compose<span class="w"> </span><span class="nb">exec</span><span class="w"> </span>v2-postgres<span class="w"> </span>psql<span class="w"> </span>-U<span class="w"> </span>changemaker<span class="w"> </span>-d<span class="w"> </span>changemaker_v2<span class="w"> </span><span class="se">\</span>
</span><span id="__span-49-3"><a id="__codelineno-49-3" name="__codelineno-49-3" href="#__codelineno-49-3"></a><span class="w"> </span>-c<span class="w"> </span><span class="s2">&quot;SELECT email FROM \&quot;User\&quot; WHERE email = &#39;test@example.com&#39;;&quot;</span>
</span><span id="__span-49-4"><a id="__codelineno-49-4" name="__codelineno-49-4" href="#__codelineno-49-4"></a>
</span><span id="__span-49-5"><a id="__codelineno-49-5" name="__codelineno-49-5" href="#__codelineno-49-5"></a><span class="c1"># Foreign key exists</span>
</span><span id="__span-49-6"><a id="__codelineno-49-6" name="__codelineno-49-6" href="#__codelineno-49-6"></a>docker<span class="w"> </span>compose<span class="w"> </span><span class="nb">exec</span><span class="w"> </span>v2-postgres<span class="w"> </span>psql<span class="w"> </span>-U<span class="w"> </span>changemaker<span class="w"> </span>-d<span class="w"> </span>changemaker_v2<span class="w"> </span><span class="se">\</span>
</span><span id="__span-49-7"><a id="__codelineno-49-7" name="__codelineno-49-7" href="#__codelineno-49-7"></a><span class="w"> </span>-c<span class="w"> </span><span class="s2">&quot;SELECT id FROM \&quot;Campaign\&quot; WHERE id = &#39;CAMPAIGN_ID&#39;;&quot;</span>
</span></code></pre></div>
<p><strong>Solution 3: Fix data</strong></p>
<p>Common fixes:</p>
<div class="language-javascript highlight"><pre><span></span><code><span id="__span-50-1"><a id="__codelineno-50-1" name="__codelineno-50-1" href="#__codelineno-50-1"></a><span class="c1">// Email already exists → Use different email</span>
</span><span id="__span-50-2"><a id="__codelineno-50-2" name="__codelineno-50-2" href="#__codelineno-50-2"></a><span class="nx">email</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;newuser@example.com&#39;</span>
</span><span id="__span-50-3"><a id="__codelineno-50-3" name="__codelineno-50-3" href="#__codelineno-50-3"></a>
</span><span id="__span-50-4"><a id="__codelineno-50-4" name="__codelineno-50-4" href="#__codelineno-50-4"></a><span class="c1">// Password too weak → Meet requirements</span>
</span><span id="__span-50-5"><a id="__codelineno-50-5" name="__codelineno-50-5" href="#__codelineno-50-5"></a><span class="nx">password</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;SecurePass123!&#39;</span><span class="w"> </span><span class="c1">// 12+ chars, upper, lower, digit</span>
</span><span id="__span-50-6"><a id="__codelineno-50-6" name="__codelineno-50-6" href="#__codelineno-50-6"></a>
</span><span id="__span-50-7"><a id="__codelineno-50-7" name="__codelineno-50-7" href="#__codelineno-50-7"></a><span class="c1">// Foreign key missing → Create parent first</span>
</span><span id="__span-50-8"><a id="__codelineno-50-8" name="__codelineno-50-8" href="#__codelineno-50-8"></a><span class="c1">// Create campaign before creating email</span>
</span><span id="__span-50-9"><a id="__codelineno-50-9" name="__codelineno-50-9" href="#__codelineno-50-9"></a>
</span><span id="__span-50-10"><a id="__codelineno-50-10" name="__codelineno-50-10" href="#__codelineno-50-10"></a><span class="c1">// Resource in use → Delete dependents first</span>
</span><span id="__span-50-11"><a id="__codelineno-50-11" name="__codelineno-50-11" href="#__codelineno-50-11"></a><span class="c1">// Delete locations before deleting cut</span>
</span></code></pre></div>
<p><strong>Solution 4: Check database schema</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-51-1"><a id="__codelineno-51-1" name="__codelineno-51-1" href="#__codelineno-51-1"></a><span class="c1"># View constraints</span>
</span><span id="__span-51-2"><a id="__codelineno-51-2" name="__codelineno-51-2" href="#__codelineno-51-2"></a>docker<span class="w"> </span>compose<span class="w"> </span><span class="nb">exec</span><span class="w"> </span>api<span class="w"> </span>npx<span class="w"> </span>prisma<span class="w"> </span>studio
</span><span id="__span-51-3"><a id="__codelineno-51-3" name="__codelineno-51-3" href="#__codelineno-51-3"></a><span class="c1"># Navigate to model, see unique fields and relations</span>
</span></code></pre></div>
<h4 id="prevention_8">Prevention<a class="headerlink" href="#prevention_8" title="Permanent link">&para;</a></h4>
<ul>
<li><strong>Client validation</strong> - Check constraints before submitting</li>
<li><strong>Clear requirements</strong> - Document validation rules</li>
<li><strong>Helpful messages</strong> - Explain how to fix</li>
<li><strong>Cascade deletes</strong> - Auto-delete dependents when safe</li>
</ul>
<hr />
<h2 id="database-errors">Database Errors<a class="headerlink" href="#database-errors" title="Permanent link">&para;</a></h2>
<h3 id="connection-refused">Connection Refused<a class="headerlink" href="#connection-refused" title="Permanent link">&para;</a></h3>
<p><strong>Severity:</strong> 🔴 Critical</p>
<h4 id="symptoms_9">Symptoms<a class="headerlink" href="#symptoms_9" title="Permanent link">&para;</a></h4>
<div class="language-text highlight"><pre><span></span><code><span id="__span-52-1"><a id="__codelineno-52-1" name="__codelineno-52-1" href="#__codelineno-52-1"></a>Error: connect ECONNREFUSED 127.0.0.1:5433
</span></code></pre></div>
<p>Or:
<div class="language-text highlight"><pre><span></span><code><span id="__span-53-1"><a id="__codelineno-53-1" name="__codelineno-53-1" href="#__codelineno-53-1"></a>Error: Can&#39;t reach database server at `v2-postgres:5432`
</span></code></pre></div></p>
<h4 id="common-causes_9">Common Causes<a class="headerlink" href="#common-causes_9" title="Permanent link">&para;</a></h4>
<ol>
<li><strong>Database not running</strong> - Container stopped</li>
<li><strong>Wrong connection string</strong> - Incorrect host/port</li>
<li><strong>Network issue</strong> - Container can't reach database</li>
<li><strong>Port conflict</strong> - Port already in use</li>
</ol>
<h4 id="solutions_9">Solutions<a class="headerlink" href="#solutions_9" title="Permanent link">&para;</a></h4>
<p><strong>Solution 1: Check database status</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-54-1"><a id="__codelineno-54-1" name="__codelineno-54-1" href="#__codelineno-54-1"></a><span class="c1"># List running containers</span>
</span><span id="__span-54-2"><a id="__codelineno-54-2" name="__codelineno-54-2" href="#__codelineno-54-2"></a>docker<span class="w"> </span>compose<span class="w"> </span>ps
</span><span id="__span-54-3"><a id="__codelineno-54-3" name="__codelineno-54-3" href="#__codelineno-54-3"></a>
</span><span id="__span-54-4"><a id="__codelineno-54-4" name="__codelineno-54-4" href="#__codelineno-54-4"></a><span class="c1"># Database should show as &quot;running&quot;</span>
</span><span id="__span-54-5"><a id="__codelineno-54-5" name="__codelineno-54-5" href="#__codelineno-54-5"></a><span class="c1"># If not:</span>
</span><span id="__span-54-6"><a id="__codelineno-54-6" name="__codelineno-54-6" href="#__codelineno-54-6"></a>docker<span class="w"> </span>compose<span class="w"> </span>up<span class="w"> </span>-d<span class="w"> </span>v2-postgres
</span></code></pre></div>
<p><strong>Solution 2: Verify connection string</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-55-1"><a id="__codelineno-55-1" name="__codelineno-55-1" href="#__codelineno-55-1"></a><span class="c1"># Check .env</span>
</span><span id="__span-55-2"><a id="__codelineno-55-2" name="__codelineno-55-2" href="#__codelineno-55-2"></a>cat<span class="w"> </span>.env<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>DATABASE_URL
</span><span id="__span-55-3"><a id="__codelineno-55-3" name="__codelineno-55-3" href="#__codelineno-55-3"></a>
</span><span id="__span-55-4"><a id="__codelineno-55-4" name="__codelineno-55-4" href="#__codelineno-55-4"></a><span class="c1"># Should be (from API container):</span>
</span><span id="__span-55-5"><a id="__codelineno-55-5" name="__codelineno-55-5" href="#__codelineno-55-5"></a><span class="nv">DATABASE_URL</span><span class="o">=</span><span class="s2">&quot;postgresql://changemaker:PASSWORD@v2-postgres:5432/changemaker_v2&quot;</span>
</span><span id="__span-55-6"><a id="__codelineno-55-6" name="__codelineno-55-6" href="#__codelineno-55-6"></a>
</span><span id="__span-55-7"><a id="__codelineno-55-7" name="__codelineno-55-7" href="#__codelineno-55-7"></a><span class="c1"># Or (from host):</span>
</span><span id="__span-55-8"><a id="__codelineno-55-8" name="__codelineno-55-8" href="#__codelineno-55-8"></a><span class="nv">DATABASE_URL</span><span class="o">=</span><span class="s2">&quot;postgresql://changemaker:PASSWORD@localhost:5433/changemaker_v2&quot;</span>
</span></code></pre></div>
<p><strong>Solution 3: Check database logs</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-56-1"><a id="__codelineno-56-1" name="__codelineno-56-1" href="#__codelineno-56-1"></a><span class="c1"># View database logs</span>
</span><span id="__span-56-2"><a id="__codelineno-56-2" name="__codelineno-56-2" href="#__codelineno-56-2"></a>docker<span class="w"> </span>compose<span class="w"> </span>logs<span class="w"> </span>v2-postgres
</span><span id="__span-56-3"><a id="__codelineno-56-3" name="__codelineno-56-3" href="#__codelineno-56-3"></a>
</span><span id="__span-56-4"><a id="__codelineno-56-4" name="__codelineno-56-4" href="#__codelineno-56-4"></a><span class="c1"># Look for:</span>
</span><span id="__span-56-5"><a id="__codelineno-56-5" name="__codelineno-56-5" href="#__codelineno-56-5"></a><span class="c1"># - &quot;database system is ready to accept connections&quot; (good)</span>
</span><span id="__span-56-6"><a id="__codelineno-56-6" name="__codelineno-56-6" href="#__codelineno-56-6"></a><span class="c1"># - &quot;FATAL: password authentication failed&quot; (bad - wrong password)</span>
</span><span id="__span-56-7"><a id="__codelineno-56-7" name="__codelineno-56-7" href="#__codelineno-56-7"></a><span class="c1"># - &quot;port 5432 already in use&quot; (bad - port conflict)</span>
</span></code></pre></div>
<p><strong>Solution 4: Test connection manually</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-57-1"><a id="__codelineno-57-1" name="__codelineno-57-1" href="#__codelineno-57-1"></a><span class="c1"># From host</span>
</span><span id="__span-57-2"><a id="__codelineno-57-2" name="__codelineno-57-2" href="#__codelineno-57-2"></a>docker<span class="w"> </span>compose<span class="w"> </span><span class="nb">exec</span><span class="w"> </span>v2-postgres<span class="w"> </span>psql<span class="w"> </span>-U<span class="w"> </span>changemaker<span class="w"> </span>-d<span class="w"> </span>changemaker_v2<span class="w"> </span>-c<span class="w"> </span><span class="s2">&quot;SELECT NOW();&quot;</span>
</span><span id="__span-57-3"><a id="__codelineno-57-3" name="__codelineno-57-3" href="#__codelineno-57-3"></a>
</span><span id="__span-57-4"><a id="__codelineno-57-4" name="__codelineno-57-4" href="#__codelineno-57-4"></a><span class="c1"># Should return current timestamp</span>
</span><span id="__span-57-5"><a id="__codelineno-57-5" name="__codelineno-57-5" href="#__codelineno-57-5"></a><span class="c1"># If fails, database isn&#39;t running properly</span>
</span></code></pre></div>
<p><strong>Solution 5: Restart database</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-58-1"><a id="__codelineno-58-1" name="__codelineno-58-1" href="#__codelineno-58-1"></a><span class="c1"># Restart database container</span>
</span><span id="__span-58-2"><a id="__codelineno-58-2" name="__codelineno-58-2" href="#__codelineno-58-2"></a>docker<span class="w"> </span>compose<span class="w"> </span>restart<span class="w"> </span>v2-postgres
</span><span id="__span-58-3"><a id="__codelineno-58-3" name="__codelineno-58-3" href="#__codelineno-58-3"></a>
</span><span id="__span-58-4"><a id="__codelineno-58-4" name="__codelineno-58-4" href="#__codelineno-58-4"></a><span class="c1"># Or recreate if corrupted</span>
</span><span id="__span-58-5"><a id="__codelineno-58-5" name="__codelineno-58-5" href="#__codelineno-58-5"></a>docker<span class="w"> </span>compose<span class="w"> </span>down<span class="w"> </span>v2-postgres
</span><span id="__span-58-6"><a id="__codelineno-58-6" name="__codelineno-58-6" href="#__codelineno-58-6"></a>docker<span class="w"> </span>compose<span class="w"> </span>up<span class="w"> </span>-d<span class="w"> </span>v2-postgres
</span><span id="__span-58-7"><a id="__codelineno-58-7" name="__codelineno-58-7" href="#__codelineno-58-7"></a>
</span><span id="__span-58-8"><a id="__codelineno-58-8" name="__codelineno-58-8" href="#__codelineno-58-8"></a><span class="c1"># Wait for &quot;ready to accept connections&quot; message</span>
</span><span id="__span-58-9"><a id="__codelineno-58-9" name="__codelineno-58-9" href="#__codelineno-58-9"></a>docker<span class="w"> </span>compose<span class="w"> </span>logs<span class="w"> </span>-f<span class="w"> </span>v2-postgres
</span></code></pre></div>
<h4 id="prevention_9">Prevention<a class="headerlink" href="#prevention_9" title="Permanent link">&para;</a></h4>
<ul>
<li><strong>Health checks</strong> - Monitor database availability</li>
<li><strong>Auto-restart</strong> - Configure restart policy</li>
<li><strong>Connection pooling</strong> - Handle transient failures</li>
<li><strong>Alerting</strong> - Alert on connection failures</li>
</ul>
<hr />
<h3 id="too-many-connections">Too Many Connections<a class="headerlink" href="#too-many-connections" title="Permanent link">&para;</a></h3>
<p><strong>Severity:</strong> 🟠 High</p>
<h4 id="symptoms_10">Symptoms<a class="headerlink" href="#symptoms_10" title="Permanent link">&para;</a></h4>
<div class="language-text highlight"><pre><span></span><code><span id="__span-59-1"><a id="__codelineno-59-1" name="__codelineno-59-1" href="#__codelineno-59-1"></a>Error: too many connections for database &quot;changemaker_v2&quot;
</span></code></pre></div>
<p>Or:
<div class="language-text highlight"><pre><span></span><code><span id="__span-60-1"><a id="__codelineno-60-1" name="__codelineno-60-1" href="#__codelineno-60-1"></a>Error: Prepared statement &quot;prisma_xxx&quot; already exists
</span></code></pre></div></p>
<h4 id="common-causes_10">Common Causes<a class="headerlink" href="#common-causes_10" title="Permanent link">&para;</a></h4>
<ol>
<li><strong>Connection leak</strong> - Connections not released</li>
<li><strong>Pool too small</strong> - Not enough connections for load</li>
<li><strong>Long-running queries</strong> - Blocking connections</li>
<li><strong>Multiple clients</strong> - Too many Prisma instances</li>
</ol>
<h4 id="solutions_10">Solutions<a class="headerlink" href="#solutions_10" title="Permanent link">&para;</a></h4>
<p><strong>Solution 1: Check active connections</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-61-1"><a id="__codelineno-61-1" name="__codelineno-61-1" href="#__codelineno-61-1"></a><span class="c1"># View connections</span>
</span><span id="__span-61-2"><a id="__codelineno-61-2" name="__codelineno-61-2" href="#__codelineno-61-2"></a>docker<span class="w"> </span>compose<span class="w"> </span><span class="nb">exec</span><span class="w"> </span>v2-postgres<span class="w"> </span>psql<span class="w"> </span>-U<span class="w"> </span>changemaker<span class="w"> </span>-d<span class="w"> </span>changemaker_v2<span class="w"> </span><span class="se">\</span>
</span><span id="__span-61-3"><a id="__codelineno-61-3" name="__codelineno-61-3" href="#__codelineno-61-3"></a><span class="w"> </span>-c<span class="w"> </span><span class="s2">&quot;SELECT count(*) FROM pg_stat_activity WHERE datname = &#39;changemaker_v2&#39;;&quot;</span>
</span><span id="__span-61-4"><a id="__codelineno-61-4" name="__codelineno-61-4" href="#__codelineno-61-4"></a>
</span><span id="__span-61-5"><a id="__codelineno-61-5" name="__codelineno-61-5" href="#__codelineno-61-5"></a><span class="c1"># PostgreSQL default max: 100 connections</span>
</span><span id="__span-61-6"><a id="__codelineno-61-6" name="__codelineno-61-6" href="#__codelineno-61-6"></a><span class="c1"># Prisma default pool: 10 connections</span>
</span></code></pre></div>
<p><strong>Solution 2: Kill idle connections</strong></p>
<div class="language-sql highlight"><pre><span></span><code><span id="__span-62-1"><a id="__codelineno-62-1" name="__codelineno-62-1" href="#__codelineno-62-1"></a><span class="c1">-- Find idle connections</span>
</span><span id="__span-62-2"><a id="__codelineno-62-2" name="__codelineno-62-2" href="#__codelineno-62-2"></a><span class="k">SELECT</span><span class="w"> </span><span class="n">pid</span><span class="p">,</span><span class="w"> </span><span class="n">usename</span><span class="p">,</span><span class="w"> </span><span class="k">state</span><span class="p">,</span><span class="w"> </span><span class="n">query_start</span>
</span><span id="__span-62-3"><a id="__codelineno-62-3" name="__codelineno-62-3" href="#__codelineno-62-3"></a><span class="k">FROM</span><span class="w"> </span><span class="n">pg_stat_activity</span>
</span><span id="__span-62-4"><a id="__codelineno-62-4" name="__codelineno-62-4" href="#__codelineno-62-4"></a><span class="k">WHERE</span><span class="w"> </span><span class="n">datname</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;changemaker_v2&#39;</span><span class="w"> </span><span class="k">AND</span><span class="w"> </span><span class="k">state</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;idle&#39;</span><span class="p">;</span>
</span><span id="__span-62-5"><a id="__codelineno-62-5" name="__codelineno-62-5" href="#__codelineno-62-5"></a>
</span><span id="__span-62-6"><a id="__codelineno-62-6" name="__codelineno-62-6" href="#__codelineno-62-6"></a><span class="c1">-- Kill specific connection</span>
</span><span id="__span-62-7"><a id="__codelineno-62-7" name="__codelineno-62-7" href="#__codelineno-62-7"></a><span class="k">SELECT</span><span class="w"> </span><span class="n">pg_terminate_backend</span><span class="p">(</span><span class="n">PID_HERE</span><span class="p">);</span>
</span><span id="__span-62-8"><a id="__codelineno-62-8" name="__codelineno-62-8" href="#__codelineno-62-8"></a>
</span><span id="__span-62-9"><a id="__codelineno-62-9" name="__codelineno-62-9" href="#__codelineno-62-9"></a><span class="c1">-- Kill all idle connections (careful!)</span>
</span><span id="__span-62-10"><a id="__codelineno-62-10" name="__codelineno-62-10" href="#__codelineno-62-10"></a><span class="k">SELECT</span><span class="w"> </span><span class="n">pg_terminate_backend</span><span class="p">(</span><span class="n">pid</span><span class="p">)</span>
</span><span id="__span-62-11"><a id="__codelineno-62-11" name="__codelineno-62-11" href="#__codelineno-62-11"></a><span class="k">FROM</span><span class="w"> </span><span class="n">pg_stat_activity</span>
</span><span id="__span-62-12"><a id="__codelineno-62-12" name="__codelineno-62-12" href="#__codelineno-62-12"></a><span class="k">WHERE</span><span class="w"> </span><span class="n">datname</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;changemaker_v2&#39;</span><span class="w"> </span><span class="k">AND</span><span class="w"> </span><span class="k">state</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;idle&#39;</span><span class="p">;</span>
</span></code></pre></div>
<p><strong>Solution 3: Adjust connection pool</strong></p>
<p>In <code>api/prisma/schema.prisma</code>:</p>
<div class="language-text highlight"><pre><span></span><code><span id="__span-63-1"><a id="__codelineno-63-1" name="__codelineno-63-1" href="#__codelineno-63-1"></a>datasource db {
</span><span id="__span-63-2"><a id="__codelineno-63-2" name="__codelineno-63-2" href="#__codelineno-63-2"></a> provider = &quot;postgresql&quot;
</span><span id="__span-63-3"><a id="__codelineno-63-3" name="__codelineno-63-3" href="#__codelineno-63-3"></a> url = env(&quot;DATABASE_URL&quot;)
</span><span id="__span-63-4"><a id="__codelineno-63-4" name="__codelineno-63-4" href="#__codelineno-63-4"></a> // Add connection pool config
</span><span id="__span-63-5"><a id="__codelineno-63-5" name="__codelineno-63-5" href="#__codelineno-63-5"></a> // connectionLimit = 10 // Default
</span><span id="__span-63-6"><a id="__codelineno-63-6" name="__codelineno-63-6" href="#__codelineno-63-6"></a>}
</span></code></pre></div>
<p>Or via DATABASE_URL:</p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-64-1"><a id="__codelineno-64-1" name="__codelineno-64-1" href="#__codelineno-64-1"></a><span class="nv">DATABASE_URL</span><span class="o">=</span><span class="s2">&quot;postgresql://user:pass@host:5432/db?connection_limit=20&quot;</span>
</span></code></pre></div>
<p><strong>Solution 4: Restart API</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-65-1"><a id="__codelineno-65-1" name="__codelineno-65-1" href="#__codelineno-65-1"></a><span class="c1"># Restart releases all connections</span>
</span><span id="__span-65-2"><a id="__codelineno-65-2" name="__codelineno-65-2" href="#__codelineno-65-2"></a>docker<span class="w"> </span>compose<span class="w"> </span>restart<span class="w"> </span>api
</span><span id="__span-65-3"><a id="__codelineno-65-3" name="__codelineno-65-3" href="#__codelineno-65-3"></a>
</span><span id="__span-65-4"><a id="__codelineno-65-4" name="__codelineno-65-4" href="#__codelineno-65-4"></a><span class="c1"># Check if connections cleared</span>
</span><span id="__span-65-5"><a id="__codelineno-65-5" name="__codelineno-65-5" href="#__codelineno-65-5"></a>docker<span class="w"> </span>compose<span class="w"> </span><span class="nb">exec</span><span class="w"> </span>v2-postgres<span class="w"> </span>psql<span class="w"> </span>-U<span class="w"> </span>changemaker<span class="w"> </span>-d<span class="w"> </span>changemaker_v2<span class="w"> </span><span class="se">\</span>
</span><span id="__span-65-6"><a id="__codelineno-65-6" name="__codelineno-65-6" href="#__codelineno-65-6"></a><span class="w"> </span>-c<span class="w"> </span><span class="s2">&quot;SELECT count(*) FROM pg_stat_activity WHERE datname = &#39;changemaker_v2&#39;;&quot;</span>
</span></code></pre></div>
<p><strong>Solution 5: Increase PostgreSQL max connections</strong></p>
<p>In <code>docker-compose.yml</code>:</p>
<div class="language-yaml highlight"><pre><span></span><code><span id="__span-66-1"><a id="__codelineno-66-1" name="__codelineno-66-1" href="#__codelineno-66-1"></a><span class="nt">v2-postgres</span><span class="p">:</span>
</span><span id="__span-66-2"><a id="__codelineno-66-2" name="__codelineno-66-2" href="#__codelineno-66-2"></a><span class="w"> </span><span class="c1"># ...</span>
</span><span id="__span-66-3"><a id="__codelineno-66-3" name="__codelineno-66-3" href="#__codelineno-66-3"></a><span class="w"> </span><span class="nt">command</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">postgres -c max_connections=200</span>
</span></code></pre></div>
<p>Then restart:</p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-67-1"><a id="__codelineno-67-1" name="__codelineno-67-1" href="#__codelineno-67-1"></a>docker<span class="w"> </span>compose<span class="w"> </span>up<span class="w"> </span>-d<span class="w"> </span>v2-postgres
</span></code></pre></div>
<h4 id="prevention_10">Prevention<a class="headerlink" href="#prevention_10" title="Permanent link">&para;</a></h4>
<ul>
<li><strong>Proper cleanup</strong> - Always close Prisma clients</li>
<li><strong>Connection pooling</strong> - Use appropriate pool size</li>
<li><strong>Monitor connections</strong> - Alert on high usage</li>
<li><strong>Query optimization</strong> - Reduce long-running queries</li>
</ul>
<hr />
<h3 id="unique-constraint-violation">Unique Constraint Violation<a class="headerlink" href="#unique-constraint-violation" title="Permanent link">&para;</a></h3>
<p><strong>Severity:</strong> 🟡 Medium</p>
<h4 id="symptoms_11">Symptoms<a class="headerlink" href="#symptoms_11" title="Permanent link">&para;</a></h4>
<div class="language-text highlight"><pre><span></span><code><span id="__span-68-1"><a id="__codelineno-68-1" name="__codelineno-68-1" href="#__codelineno-68-1"></a>Error: Unique constraint failed on the fields: (`email`)
</span></code></pre></div>
<p>Or:
<div class="language-text highlight"><pre><span></span><code><span id="__span-69-1"><a id="__codelineno-69-1" name="__codelineno-69-1" href="#__codelineno-69-1"></a>PrismaClientKnownRequestError:
</span><span id="__span-69-2"><a id="__codelineno-69-2" name="__codelineno-69-2" href="#__codelineno-69-2"></a>Unique constraint failed on the constraint: `User_email_key`
</span></code></pre></div></p>
<h4 id="common-causes_11">Common Causes<a class="headerlink" href="#common-causes_11" title="Permanent link">&para;</a></h4>
<ol>
<li><strong>Duplicate email</strong> - User already exists</li>
<li><strong>Race condition</strong> - Two creates at same time</li>
<li><strong>Case sensitivity</strong> - Email differs only in case</li>
<li><strong>Retry logic</strong> - Request sent multiple times</li>
</ol>
<h4 id="solutions_11">Solutions<a class="headerlink" href="#solutions_11" title="Permanent link">&para;</a></h4>
<p><strong>Solution 1: Check existing records</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-70-1"><a id="__codelineno-70-1" name="__codelineno-70-1" href="#__codelineno-70-1"></a><span class="c1"># Find duplicate</span>
</span><span id="__span-70-2"><a id="__codelineno-70-2" name="__codelineno-70-2" href="#__codelineno-70-2"></a>docker<span class="w"> </span>compose<span class="w"> </span><span class="nb">exec</span><span class="w"> </span>v2-postgres<span class="w"> </span>psql<span class="w"> </span>-U<span class="w"> </span>changemaker<span class="w"> </span>-d<span class="w"> </span>changemaker_v2<span class="w"> </span><span class="se">\</span>
</span><span id="__span-70-3"><a id="__codelineno-70-3" name="__codelineno-70-3" href="#__codelineno-70-3"></a><span class="w"> </span>-c<span class="w"> </span><span class="s2">&quot;SELECT id, email, \&quot;createdAt\&quot; FROM \&quot;User\&quot; WHERE email = &#39;duplicate@example.com&#39;;&quot;</span>
</span></code></pre></div>
<p><strong>Solution 2: Update instead of create</strong></p>
<div class="language-javascript highlight"><pre><span></span><code><span id="__span-71-1"><a id="__codelineno-71-1" name="__codelineno-71-1" href="#__codelineno-71-1"></a><span class="c1">// Instead of:</span>
</span><span id="__span-71-2"><a id="__codelineno-71-2" name="__codelineno-71-2" href="#__codelineno-71-2"></a><span class="k">await</span><span class="w"> </span><span class="nx">prisma</span><span class="p">.</span><span class="nx">user</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span><span class="w"> </span><span class="nx">data</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">email</span><span class="p">,</span><span class="w"> </span><span class="p">...</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">});</span>
</span><span id="__span-71-3"><a id="__codelineno-71-3" name="__codelineno-71-3" href="#__codelineno-71-3"></a>
</span><span id="__span-71-4"><a id="__codelineno-71-4" name="__codelineno-71-4" href="#__codelineno-71-4"></a><span class="c1">// Use upsert:</span>
</span><span id="__span-71-5"><a id="__codelineno-71-5" name="__codelineno-71-5" href="#__codelineno-71-5"></a><span class="k">await</span><span class="w"> </span><span class="nx">prisma</span><span class="p">.</span><span class="nx">user</span><span class="p">.</span><span class="nx">upsert</span><span class="p">({</span>
</span><span id="__span-71-6"><a id="__codelineno-71-6" name="__codelineno-71-6" href="#__codelineno-71-6"></a><span class="w"> </span><span class="nx">where</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">email</span><span class="w"> </span><span class="p">},</span>
</span><span id="__span-71-7"><a id="__codelineno-71-7" name="__codelineno-71-7" href="#__codelineno-71-7"></a><span class="w"> </span><span class="nx">update</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">name</span><span class="p">,</span><span class="w"> </span><span class="p">...</span><span class="w"> </span><span class="p">},</span>
</span><span id="__span-71-8"><a id="__codelineno-71-8" name="__codelineno-71-8" href="#__codelineno-71-8"></a><span class="w"> </span><span class="nx">create</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">email</span><span class="p">,</span><span class="w"> </span><span class="nx">name</span><span class="p">,</span><span class="w"> </span><span class="p">...</span><span class="w"> </span><span class="p">}</span>
</span><span id="__span-71-9"><a id="__codelineno-71-9" name="__codelineno-71-9" href="#__codelineno-71-9"></a><span class="p">});</span>
</span></code></pre></div>
<p><strong>Solution 3: Handle error gracefully</strong></p>
<div class="language-javascript highlight"><pre><span></span><code><span id="__span-72-1"><a id="__codelineno-72-1" name="__codelineno-72-1" href="#__codelineno-72-1"></a><span class="k">try</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-72-2"><a id="__codelineno-72-2" name="__codelineno-72-2" href="#__codelineno-72-2"></a><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">prisma</span><span class="p">.</span><span class="nx">user</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span><span class="w"> </span><span class="nx">data</span><span class="w"> </span><span class="p">});</span>
</span><span id="__span-72-3"><a id="__codelineno-72-3" name="__codelineno-72-3" href="#__codelineno-72-3"></a><span class="p">}</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="p">(</span><span class="nx">error</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-72-4"><a id="__codelineno-72-4" name="__codelineno-72-4" href="#__codelineno-72-4"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">error</span><span class="p">.</span><span class="nx">code</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="s1">&#39;P2002&#39;</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-72-5"><a id="__codelineno-72-5" name="__codelineno-72-5" href="#__codelineno-72-5"></a><span class="w"> </span><span class="c1">// Unique constraint violation</span>
</span><span id="__span-72-6"><a id="__codelineno-72-6" name="__codelineno-72-6" href="#__codelineno-72-6"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">field</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">error</span><span class="p">.</span><span class="nx">meta</span><span class="o">?</span><span class="p">.</span><span class="nx">target</span><span class="o">?</span><span class="p">.[</span><span class="mf">0</span><span class="p">];</span>
</span><span id="__span-72-7"><a id="__codelineno-72-7" name="__codelineno-72-7" href="#__codelineno-72-7"></a><span class="w"> </span><span class="k">throw</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="ne">Error</span><span class="p">(</span><span class="sb">`</span><span class="si">${</span><span class="nx">field</span><span class="si">}</span><span class="sb"> already exists`</span><span class="p">);</span>
</span><span id="__span-72-8"><a id="__codelineno-72-8" name="__codelineno-72-8" href="#__codelineno-72-8"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-72-9"><a id="__codelineno-72-9" name="__codelineno-72-9" href="#__codelineno-72-9"></a><span class="w"> </span><span class="k">throw</span><span class="w"> </span><span class="nx">error</span><span class="p">;</span>
</span><span id="__span-72-10"><a id="__codelineno-72-10" name="__codelineno-72-10" href="#__codelineno-72-10"></a><span class="p">}</span>
</span></code></pre></div>
<p><strong>Solution 4: Delete duplicate</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-73-1"><a id="__codelineno-73-1" name="__codelineno-73-1" href="#__codelineno-73-1"></a><span class="c1"># If truly duplicate, delete one</span>
</span><span id="__span-73-2"><a id="__codelineno-73-2" name="__codelineno-73-2" href="#__codelineno-73-2"></a>docker<span class="w"> </span>compose<span class="w"> </span><span class="nb">exec</span><span class="w"> </span>v2-postgres<span class="w"> </span>psql<span class="w"> </span>-U<span class="w"> </span>changemaker<span class="w"> </span>-d<span class="w"> </span>changemaker_v2<span class="w"> </span><span class="se">\</span>
</span><span id="__span-73-3"><a id="__codelineno-73-3" name="__codelineno-73-3" href="#__codelineno-73-3"></a><span class="w"> </span>-c<span class="w"> </span><span class="s2">&quot;DELETE FROM \&quot;User\&quot; WHERE id = &#39;ID_TO_DELETE&#39;;&quot;</span>
</span></code></pre></div>
<h4 id="prevention_11">Prevention<a class="headerlink" href="#prevention_11" title="Permanent link">&para;</a></h4>
<ul>
<li><strong>Check before create</strong> - Query first to check existence</li>
<li><strong>Use upsert</strong> - Update or create atomically</li>
<li><strong>Unique indexes</strong> - Database enforces uniqueness</li>
<li><strong>Case normalization</strong> - Store emails lowercase</li>
</ul>
<hr />
<h3 id="foreign-key-constraint">Foreign Key Constraint<a class="headerlink" href="#foreign-key-constraint" title="Permanent link">&para;</a></h3>
<p><strong>Severity:</strong> 🟡 Medium</p>
<h4 id="symptoms_12">Symptoms<a class="headerlink" href="#symptoms_12" title="Permanent link">&para;</a></h4>
<div class="language-text highlight"><pre><span></span><code><span id="__span-74-1"><a id="__codelineno-74-1" name="__codelineno-74-1" href="#__codelineno-74-1"></a>Error: Foreign key constraint failed on the field: `campaignId`
</span></code></pre></div>
<p>Or:
<div class="language-text highlight"><pre><span></span><code><span id="__span-75-1"><a id="__codelineno-75-1" name="__codelineno-75-1" href="#__codelineno-75-1"></a>Error: An operation failed because it depends on one or more records that were required but not found. Record to update not found.
</span></code></pre></div></p>
<h4 id="common-causes_12">Common Causes<a class="headerlink" href="#common-causes_12" title="Permanent link">&para;</a></h4>
<ol>
<li><strong>Parent doesn't exist</strong> - Referenced record missing</li>
<li><strong>Wrong ID</strong> - Typo in foreign key value</li>
<li><strong>Delete order</strong> - Trying to delete parent before children</li>
<li><strong>Null constraint</strong> - Foreign key required but null provided</li>
</ol>
<h4 id="solutions_12">Solutions<a class="headerlink" href="#solutions_12" title="Permanent link">&para;</a></h4>
<p><strong>Solution 1: Verify parent exists</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-76-1"><a id="__codelineno-76-1" name="__codelineno-76-1" href="#__codelineno-76-1"></a><span class="c1"># Check campaign exists</span>
</span><span id="__span-76-2"><a id="__codelineno-76-2" name="__codelineno-76-2" href="#__codelineno-76-2"></a>docker<span class="w"> </span>compose<span class="w"> </span><span class="nb">exec</span><span class="w"> </span>v2-postgres<span class="w"> </span>psql<span class="w"> </span>-U<span class="w"> </span>changemaker<span class="w"> </span>-d<span class="w"> </span>changemaker_v2<span class="w"> </span><span class="se">\</span>
</span><span id="__span-76-3"><a id="__codelineno-76-3" name="__codelineno-76-3" href="#__codelineno-76-3"></a><span class="w"> </span>-c<span class="w"> </span><span class="s2">&quot;SELECT id, name FROM \&quot;Campaign\&quot; WHERE id = &#39;CAMPAIGN_ID&#39;;&quot;</span>
</span></code></pre></div>
<p><strong>Solution 2: Create parent first</strong></p>
<div class="language-javascript highlight"><pre><span></span><code><span id="__span-77-1"><a id="__codelineno-77-1" name="__codelineno-77-1" href="#__codelineno-77-1"></a><span class="c1">// Create campaign first</span>
</span><span id="__span-77-2"><a id="__codelineno-77-2" name="__codelineno-77-2" href="#__codelineno-77-2"></a><span class="kd">const</span><span class="w"> </span><span class="nx">campaign</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">prisma</span><span class="p">.</span><span class="nx">campaign</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
</span><span id="__span-77-3"><a id="__codelineno-77-3" name="__codelineno-77-3" href="#__codelineno-77-3"></a><span class="w"> </span><span class="nx">data</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">name</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;My Campaign&#39;</span><span class="p">,</span><span class="w"> </span><span class="p">...</span><span class="w"> </span><span class="p">}</span>
</span><span id="__span-77-4"><a id="__codelineno-77-4" name="__codelineno-77-4" href="#__codelineno-77-4"></a><span class="p">});</span>
</span><span id="__span-77-5"><a id="__codelineno-77-5" name="__codelineno-77-5" href="#__codelineno-77-5"></a>
</span><span id="__span-77-6"><a id="__codelineno-77-6" name="__codelineno-77-6" href="#__codelineno-77-6"></a><span class="c1">// Then create email with campaignId</span>
</span><span id="__span-77-7"><a id="__codelineno-77-7" name="__codelineno-77-7" href="#__codelineno-77-7"></a><span class="kd">const</span><span class="w"> </span><span class="nx">email</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">prisma</span><span class="p">.</span><span class="nx">campaignEmail</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
</span><span id="__span-77-8"><a id="__codelineno-77-8" name="__codelineno-77-8" href="#__codelineno-77-8"></a><span class="w"> </span><span class="nx">data</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-77-9"><a id="__codelineno-77-9" name="__codelineno-77-9" href="#__codelineno-77-9"></a><span class="w"> </span><span class="nx">campaignId</span><span class="o">:</span><span class="w"> </span><span class="nx">campaign</span><span class="p">.</span><span class="nx">id</span><span class="p">,</span><span class="w"> </span><span class="c1">// Use created campaign&#39;s ID</span>
</span><span id="__span-77-10"><a id="__codelineno-77-10" name="__codelineno-77-10" href="#__codelineno-77-10"></a><span class="w"> </span><span class="p">...</span>
</span><span id="__span-77-11"><a id="__codelineno-77-11" name="__codelineno-77-11" href="#__codelineno-77-11"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-77-12"><a id="__codelineno-77-12" name="__codelineno-77-12" href="#__codelineno-77-12"></a><span class="p">});</span>
</span></code></pre></div>
<p><strong>Solution 3: Delete children first</strong></p>
<div class="language-javascript highlight"><pre><span></span><code><span id="__span-78-1"><a id="__codelineno-78-1" name="__codelineno-78-1" href="#__codelineno-78-1"></a><span class="c1">// Delete all emails in campaign</span>
</span><span id="__span-78-2"><a id="__codelineno-78-2" name="__codelineno-78-2" href="#__codelineno-78-2"></a><span class="k">await</span><span class="w"> </span><span class="nx">prisma</span><span class="p">.</span><span class="nx">campaignEmail</span><span class="p">.</span><span class="nx">deleteMany</span><span class="p">({</span>
</span><span id="__span-78-3"><a id="__codelineno-78-3" name="__codelineno-78-3" href="#__codelineno-78-3"></a><span class="w"> </span><span class="nx">where</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">campaignId</span><span class="w"> </span><span class="p">}</span>
</span><span id="__span-78-4"><a id="__codelineno-78-4" name="__codelineno-78-4" href="#__codelineno-78-4"></a><span class="p">});</span>
</span><span id="__span-78-5"><a id="__codelineno-78-5" name="__codelineno-78-5" href="#__codelineno-78-5"></a>
</span><span id="__span-78-6"><a id="__codelineno-78-6" name="__codelineno-78-6" href="#__codelineno-78-6"></a><span class="c1">// Then delete campaign</span>
</span><span id="__span-78-7"><a id="__codelineno-78-7" name="__codelineno-78-7" href="#__codelineno-78-7"></a><span class="k">await</span><span class="w"> </span><span class="nx">prisma</span><span class="p">.</span><span class="nx">campaign</span><span class="p">.</span><span class="ow">delete</span><span class="p">({</span>
</span><span id="__span-78-8"><a id="__codelineno-78-8" name="__codelineno-78-8" href="#__codelineno-78-8"></a><span class="w"> </span><span class="nx">where</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">id</span><span class="o">:</span><span class="w"> </span><span class="nx">campaignId</span><span class="w"> </span><span class="p">}</span>
</span><span id="__span-78-9"><a id="__codelineno-78-9" name="__codelineno-78-9" href="#__codelineno-78-9"></a><span class="p">});</span>
</span><span id="__span-78-10"><a id="__codelineno-78-10" name="__codelineno-78-10" href="#__codelineno-78-10"></a>
</span><span id="__span-78-11"><a id="__codelineno-78-11" name="__codelineno-78-11" href="#__codelineno-78-11"></a><span class="c1">// Or use cascade delete in schema:</span>
</span><span id="__span-78-12"><a id="__codelineno-78-12" name="__codelineno-78-12" href="#__codelineno-78-12"></a><span class="c1">// @@relation(onDelete: Cascade)</span>
</span></code></pre></div>
<p><strong>Solution 4: Use transactions</strong></p>
<div class="language-javascript highlight"><pre><span></span><code><span id="__span-79-1"><a id="__codelineno-79-1" name="__codelineno-79-1" href="#__codelineno-79-1"></a><span class="c1">// Ensure atomicity</span>
</span><span id="__span-79-2"><a id="__codelineno-79-2" name="__codelineno-79-2" href="#__codelineno-79-2"></a><span class="k">await</span><span class="w"> </span><span class="nx">prisma</span><span class="p">.</span><span class="nx">$transaction</span><span class="p">([</span>
</span><span id="__span-79-3"><a id="__codelineno-79-3" name="__codelineno-79-3" href="#__codelineno-79-3"></a><span class="w"> </span><span class="nx">prisma</span><span class="p">.</span><span class="nx">campaignEmail</span><span class="p">.</span><span class="nx">deleteMany</span><span class="p">({</span><span class="w"> </span><span class="nx">where</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">campaignId</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}),</span>
</span><span id="__span-79-4"><a id="__codelineno-79-4" name="__codelineno-79-4" href="#__codelineno-79-4"></a><span class="w"> </span><span class="nx">prisma</span><span class="p">.</span><span class="nx">campaign</span><span class="p">.</span><span class="ow">delete</span><span class="p">({</span><span class="w"> </span><span class="nx">where</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">id</span><span class="o">:</span><span class="w"> </span><span class="nx">campaignId</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">})</span>
</span><span id="__span-79-5"><a id="__codelineno-79-5" name="__codelineno-79-5" href="#__codelineno-79-5"></a><span class="p">]);</span>
</span></code></pre></div>
<h4 id="prevention_12">Prevention<a class="headerlink" href="#prevention_12" title="Permanent link">&para;</a></h4>
<ul>
<li><strong>Cascade deletes</strong> - Configure in schema where appropriate</li>
<li><strong>Soft deletes</strong> - Flag as deleted instead of removing</li>
<li><strong>Validation</strong> - Check foreign keys exist before creating</li>
<li><strong>Transactions</strong> - Use for multi-step operations</li>
</ul>
<hr />
<h2 id="frontend-errors">Frontend Errors<a class="headerlink" href="#frontend-errors" title="Permanent link">&para;</a></h2>
<h3 id="network-error">Network Error<a class="headerlink" href="#network-error" title="Permanent link">&para;</a></h3>
<p><strong>Severity:</strong> 🟠 High</p>
<h4 id="symptoms_13">Symptoms<a class="headerlink" href="#symptoms_13" title="Permanent link">&para;</a></h4>
<p>Browser console:
<div class="language-text highlight"><pre><span></span><code><span id="__span-80-1"><a id="__codelineno-80-1" name="__codelineno-80-1" href="#__codelineno-80-1"></a>Error: Network Error
</span></code></pre></div></p>
<p>Or:
<div class="language-text highlight"><pre><span></span><code><span id="__span-81-1"><a id="__codelineno-81-1" name="__codelineno-81-1" href="#__codelineno-81-1"></a>AxiosError: Request failed with status code undefined
</span></code></pre></div></p>
<p>User sees: API request fails, loading spinner never stops.</p>
<h4 id="common-causes_13">Common Causes<a class="headerlink" href="#common-causes_13" title="Permanent link">&para;</a></h4>
<ol>
<li><strong>API down</strong> - API container not running</li>
<li><strong>Wrong API URL</strong> - VITE_API_URL misconfigured</li>
<li><strong>CORS issue</strong> - Browser blocking request</li>
<li><strong>Network timeout</strong> - Request taking too long</li>
</ol>
<h4 id="solutions_13">Solutions<a class="headerlink" href="#solutions_13" title="Permanent link">&para;</a></h4>
<p><strong>Solution 1: Check API status</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-82-1"><a id="__codelineno-82-1" name="__codelineno-82-1" href="#__codelineno-82-1"></a><span class="c1"># Is API running?</span>
</span><span id="__span-82-2"><a id="__codelineno-82-2" name="__codelineno-82-2" href="#__codelineno-82-2"></a>docker<span class="w"> </span>compose<span class="w"> </span>ps<span class="w"> </span>api
</span><span id="__span-82-3"><a id="__codelineno-82-3" name="__codelineno-82-3" href="#__codelineno-82-3"></a>
</span><span id="__span-82-4"><a id="__codelineno-82-4" name="__codelineno-82-4" href="#__codelineno-82-4"></a><span class="c1"># Check API logs</span>
</span><span id="__span-82-5"><a id="__codelineno-82-5" name="__codelineno-82-5" href="#__codelineno-82-5"></a>docker<span class="w"> </span>compose<span class="w"> </span>logs<span class="w"> </span>api<span class="w"> </span>--tail<span class="o">=</span><span class="m">50</span>
</span><span id="__span-82-6"><a id="__codelineno-82-6" name="__codelineno-82-6" href="#__codelineno-82-6"></a>
</span><span id="__span-82-7"><a id="__codelineno-82-7" name="__codelineno-82-7" href="#__codelineno-82-7"></a><span class="c1"># Test API directly</span>
</span><span id="__span-82-8"><a id="__codelineno-82-8" name="__codelineno-82-8" href="#__codelineno-82-8"></a>curl<span class="w"> </span>http://localhost:4000/api/health
</span></code></pre></div>
<p><strong>Solution 2: Verify API URL</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-83-1"><a id="__codelineno-83-1" name="__codelineno-83-1" href="#__codelineno-83-1"></a><span class="c1"># Check admin .env</span>
</span><span id="__span-83-2"><a id="__codelineno-83-2" name="__codelineno-83-2" href="#__codelineno-83-2"></a>cat<span class="w"> </span>admin/.env
</span><span id="__span-83-3"><a id="__codelineno-83-3" name="__codelineno-83-3" href="#__codelineno-83-3"></a>
</span><span id="__span-83-4"><a id="__codelineno-83-4" name="__codelineno-83-4" href="#__codelineno-83-4"></a><span class="c1"># Should have:</span>
</span><span id="__span-83-5"><a id="__codelineno-83-5" name="__codelineno-83-5" href="#__codelineno-83-5"></a><span class="nv">VITE_API_URL</span><span class="o">=</span>http://localhost:4000
</span><span id="__span-83-6"><a id="__codelineno-83-6" name="__codelineno-83-6" href="#__codelineno-83-6"></a>
</span><span id="__span-83-7"><a id="__codelineno-83-7" name="__codelineno-83-7" href="#__codelineno-83-7"></a><span class="c1"># In Docker, use:</span>
</span><span id="__span-83-8"><a id="__codelineno-83-8" name="__codelineno-83-8" href="#__codelineno-83-8"></a><span class="nv">VITE_API_URL</span><span class="o">=</span>http://api:4000
</span></code></pre></div>
<p><strong>Solution 3: Check browser console</strong></p>
<p>Press F12, check:</p>
<ul>
<li><strong>Network tab</strong> - Does request appear? What's the status?</li>
<li><strong>Console tab</strong> - Any CORS errors?</li>
</ul>
<p><strong>Solution 4: Test from different client</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-84-1"><a id="__codelineno-84-1" name="__codelineno-84-1" href="#__codelineno-84-1"></a><span class="c1"># From command line</span>
</span><span id="__span-84-2"><a id="__codelineno-84-2" name="__codelineno-84-2" href="#__codelineno-84-2"></a>curl<span class="w"> </span>http://localhost:4000/api/campaigns
</span><span id="__span-84-3"><a id="__codelineno-84-3" name="__codelineno-84-3" href="#__codelineno-84-3"></a>
</span><span id="__span-84-4"><a id="__codelineno-84-4" name="__codelineno-84-4" href="#__codelineno-84-4"></a><span class="c1"># If this works but browser doesn&#39;t, it&#39;s a CORS issue</span>
</span></code></pre></div>
<h4 id="prevention_13">Prevention<a class="headerlink" href="#prevention_13" title="Permanent link">&para;</a></h4>
<ul>
<li><strong>Health checks</strong> - Monitor API availability</li>
<li><strong>Error boundaries</strong> - Catch and display network errors</li>
<li><strong>Retry logic</strong> - Auto-retry failed requests</li>
<li><strong>Offline detection</strong> - Detect and handle offline state</li>
</ul>
<hr />
<h3 id="cors-errors">CORS Errors<a class="headerlink" href="#cors-errors" title="Permanent link">&para;</a></h3>
<p><strong>Severity:</strong> 🟠 High</p>
<h4 id="symptoms_14">Symptoms<a class="headerlink" href="#symptoms_14" title="Permanent link">&para;</a></h4>
<p>Browser console:
<div class="language-text highlight"><pre><span></span><code><span id="__span-85-1"><a id="__codelineno-85-1" name="__codelineno-85-1" href="#__codelineno-85-1"></a>Access to XMLHttpRequest at &#39;http://localhost:4000/api/users&#39; from origin
</span><span id="__span-85-2"><a id="__codelineno-85-2" name="__codelineno-85-2" href="#__codelineno-85-2"></a>&#39;http://localhost:3000&#39; has been blocked by CORS policy: No
</span><span id="__span-85-3"><a id="__codelineno-85-3" name="__codelineno-85-3" href="#__codelineno-85-3"></a>&#39;Access-Control-Allow-Origin&#39; header is present on the requested resource.
</span></code></pre></div></p>
<h4 id="common-causes_14">Common Causes<a class="headerlink" href="#common-causes_14" title="Permanent link">&para;</a></h4>
<ol>
<li><strong>Missing CORS config</strong> - API not configured for CORS</li>
<li><strong>Wrong origin</strong> - Admin URL not in allowed origins</li>
<li><strong>Credentials flag</strong> - withCredentials set but not allowed</li>
<li><strong>Preflight failure</strong> - OPTIONS request failing</li>
</ol>
<h4 id="solutions_14">Solutions<a class="headerlink" href="#solutions_14" title="Permanent link">&para;</a></h4>
<p><strong>Solution 1: Check API CORS configuration</strong></p>
<p>In <code>api/src/server.ts</code>:</p>
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-86-1"><a id="__codelineno-86-1" name="__codelineno-86-1" href="#__codelineno-86-1"></a><span class="nx">app</span><span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="nx">cors</span><span class="p">({</span>
</span><span id="__span-86-2"><a id="__codelineno-86-2" name="__codelineno-86-2" href="#__codelineno-86-2"></a><span class="w"> </span><span class="nx">origin</span><span class="o">:</span><span class="w"> </span><span class="kt">process.env.CORS_ORIGINS?.split</span><span class="p">(</span><span class="s1">&#39;,&#39;</span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">[</span><span class="s1">&#39;http://localhost:3000&#39;</span><span class="p">],</span>
</span><span id="__span-86-3"><a id="__codelineno-86-3" name="__codelineno-86-3" href="#__codelineno-86-3"></a><span class="w"> </span><span class="nx">credentials</span><span class="o">:</span><span class="w"> </span><span class="kt">true</span>
</span><span id="__span-86-4"><a id="__codelineno-86-4" name="__codelineno-86-4" href="#__codelineno-86-4"></a><span class="p">}));</span>
</span></code></pre></div>
<p><strong>Solution 2: Verify CORS_ORIGINS</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-87-1"><a id="__codelineno-87-1" name="__codelineno-87-1" href="#__codelineno-87-1"></a><span class="c1"># Check .env</span>
</span><span id="__span-87-2"><a id="__codelineno-87-2" name="__codelineno-87-2" href="#__codelineno-87-2"></a>cat<span class="w"> </span>.env<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>CORS_ORIGINS
</span><span id="__span-87-3"><a id="__codelineno-87-3" name="__codelineno-87-3" href="#__codelineno-87-3"></a>
</span><span id="__span-87-4"><a id="__codelineno-87-4" name="__codelineno-87-4" href="#__codelineno-87-4"></a><span class="c1"># Should include admin URL:</span>
</span><span id="__span-87-5"><a id="__codelineno-87-5" name="__codelineno-87-5" href="#__codelineno-87-5"></a><span class="nv">CORS_ORIGINS</span><span class="o">=</span>http://localhost:3000,https://app.cmlite.org
</span></code></pre></div>
<p><strong>Solution 3: Add origin temporarily</strong></p>
<p>For development:</p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-88-1"><a id="__codelineno-88-1" name="__codelineno-88-1" href="#__codelineno-88-1"></a><span class="c1"># In .env</span>
</span><span id="__span-88-2"><a id="__codelineno-88-2" name="__codelineno-88-2" href="#__codelineno-88-2"></a><span class="nv">CORS_ORIGINS</span><span class="o">=</span>*<span class="w"> </span><span class="c1"># Allow all origins (dev only!)</span>
</span><span id="__span-88-3"><a id="__codelineno-88-3" name="__codelineno-88-3" href="#__codelineno-88-3"></a>
</span><span id="__span-88-4"><a id="__codelineno-88-4" name="__codelineno-88-4" href="#__codelineno-88-4"></a><span class="c1"># Restart API</span>
</span><span id="__span-88-5"><a id="__codelineno-88-5" name="__codelineno-88-5" href="#__codelineno-88-5"></a>docker<span class="w"> </span>compose<span class="w"> </span>restart<span class="w"> </span>api
</span></code></pre></div>
<p><strong>Solution 4: Check preflight request</strong></p>
<p>In browser Network tab:</p>
<ol>
<li>Find OPTIONS request before actual request</li>
<li>Check if it returns 200 OK</li>
<li>Check response headers include:</li>
<li>Access-Control-Allow-Origin</li>
<li>Access-Control-Allow-Methods</li>
<li>Access-Control-Allow-Headers</li>
</ol>
<h4 id="prevention_14">Prevention<a class="headerlink" href="#prevention_14" title="Permanent link">&para;</a></h4>
<ul>
<li><strong>Explicit origins</strong> - List all allowed origins</li>
<li><strong>Environment-based</strong> - Different origins per environment</li>
<li><strong>Credentials support</strong> - Enable if using cookies/auth</li>
<li><strong>Preflight caching</strong> - Cache OPTIONS responses</li>
</ul>
<div class="admonition warning">
<p class="admonition-title">Security Note</p>
<p>Never use <code>CORS_ORIGINS=*</code> in production with credentials enabled.</p>
</div>
<hr />
<h3 id="module-not-found">Module Not Found<a class="headerlink" href="#module-not-found" title="Permanent link">&para;</a></h3>
<p><strong>Severity:</strong> 🟡 Medium</p>
<h4 id="symptoms_15">Symptoms<a class="headerlink" href="#symptoms_15" title="Permanent link">&para;</a></h4>
<div class="language-text highlight"><pre><span></span><code><span id="__span-89-1"><a id="__codelineno-89-1" name="__codelineno-89-1" href="#__codelineno-89-1"></a>Error: Cannot find module &#39;@/components/MyComponent&#39;
</span></code></pre></div>
<p>Or:
<div class="language-text highlight"><pre><span></span><code><span id="__span-90-1"><a id="__codelineno-90-1" name="__codelineno-90-1" href="#__codelineno-90-1"></a>Module not found: Can&#39;t resolve &#39;some-package&#39;
</span></code></pre></div></p>
<h4 id="common-causes_15">Common Causes<a class="headerlink" href="#common-causes_15" title="Permanent link">&para;</a></h4>
<ol>
<li><strong>Missing dependency</strong> - Package not installed</li>
<li><strong>Wrong import path</strong> - Typo in path</li>
<li><strong>Path alias issue</strong> - @ alias not configured</li>
<li><strong>Case sensitivity</strong> - Wrong case in filename</li>
</ol>
<h4 id="solutions_15">Solutions<a class="headerlink" href="#solutions_15" title="Permanent link">&para;</a></h4>
<p><strong>Solution 1: Install missing package</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-91-1"><a id="__codelineno-91-1" name="__codelineno-91-1" href="#__codelineno-91-1"></a><span class="nb">cd</span><span class="w"> </span>admin
</span><span id="__span-91-2"><a id="__codelineno-91-2" name="__codelineno-91-2" href="#__codelineno-91-2"></a>
</span><span id="__span-91-3"><a id="__codelineno-91-3" name="__codelineno-91-3" href="#__codelineno-91-3"></a><span class="c1"># Install package</span>
</span><span id="__span-91-4"><a id="__codelineno-91-4" name="__codelineno-91-4" href="#__codelineno-91-4"></a>npm<span class="w"> </span>install<span class="w"> </span>some-package
</span><span id="__span-91-5"><a id="__codelineno-91-5" name="__codelineno-91-5" href="#__codelineno-91-5"></a>
</span><span id="__span-91-6"><a id="__codelineno-91-6" name="__codelineno-91-6" href="#__codelineno-91-6"></a><span class="c1"># Or if dev dependency</span>
</span><span id="__span-91-7"><a id="__codelineno-91-7" name="__codelineno-91-7" href="#__codelineno-91-7"></a>npm<span class="w"> </span>install<span class="w"> </span>-D<span class="w"> </span>some-package
</span><span id="__span-91-8"><a id="__codelineno-91-8" name="__codelineno-91-8" href="#__codelineno-91-8"></a>
</span><span id="__span-91-9"><a id="__codelineno-91-9" name="__codelineno-91-9" href="#__codelineno-91-9"></a><span class="c1"># Restart dev server</span>
</span><span id="__span-91-10"><a id="__codelineno-91-10" name="__codelineno-91-10" href="#__codelineno-91-10"></a>npm<span class="w"> </span>run<span class="w"> </span>dev
</span></code></pre></div>
<p><strong>Solution 2: Check import path</strong></p>
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-92-1"><a id="__codelineno-92-1" name="__codelineno-92-1" href="#__codelineno-92-1"></a><span class="c1">// Wrong:</span>
</span><span id="__span-92-2"><a id="__codelineno-92-2" name="__codelineno-92-2" href="#__codelineno-92-2"></a><span class="k">import</span><span class="w"> </span><span class="nx">MyComponent</span><span class="w"> </span><span class="kr">from</span><span class="w"> </span><span class="s1">&#39;@/Component/MyComponent&#39;</span><span class="p">;</span>
</span><span id="__span-92-3"><a id="__codelineno-92-3" name="__codelineno-92-3" href="#__codelineno-92-3"></a>
</span><span id="__span-92-4"><a id="__codelineno-92-4" name="__codelineno-92-4" href="#__codelineno-92-4"></a><span class="c1">// Right:</span>
</span><span id="__span-92-5"><a id="__codelineno-92-5" name="__codelineno-92-5" href="#__codelineno-92-5"></a><span class="k">import</span><span class="w"> </span><span class="nx">MyComponent</span><span class="w"> </span><span class="kr">from</span><span class="w"> </span><span class="s1">&#39;@/components/MyComponent&#39;</span><span class="p">;</span>
</span><span id="__span-92-6"><a id="__codelineno-92-6" name="__codelineno-92-6" href="#__codelineno-92-6"></a>
</span><span id="__span-92-7"><a id="__codelineno-92-7" name="__codelineno-92-7" href="#__codelineno-92-7"></a><span class="c1">// Verify file exists:</span>
</span><span id="__span-92-8"><a id="__codelineno-92-8" name="__codelineno-92-8" href="#__codelineno-92-8"></a><span class="c1">// admin/src/components/MyComponent.tsx</span>
</span></code></pre></div>
<p><strong>Solution 3: Verify path alias</strong></p>
<p>In <code>admin/vite.config.ts</code>:</p>
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-93-1"><a id="__codelineno-93-1" name="__codelineno-93-1" href="#__codelineno-93-1"></a><span class="k">export</span><span class="w"> </span><span class="k">default</span><span class="w"> </span><span class="nx">defineConfig</span><span class="p">({</span>
</span><span id="__span-93-2"><a id="__codelineno-93-2" name="__codelineno-93-2" href="#__codelineno-93-2"></a><span class="w"> </span><span class="nx">resolve</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-93-3"><a id="__codelineno-93-3" name="__codelineno-93-3" href="#__codelineno-93-3"></a><span class="w"> </span><span class="nx">alias</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-93-4"><a id="__codelineno-93-4" name="__codelineno-93-4" href="#__codelineno-93-4"></a><span class="w"> </span><span class="s1">&#39;@&#39;</span><span class="o">:</span><span class="w"> </span><span class="nx">path</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="nx">__dirname</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;./src&#39;</span><span class="p">)</span>
</span><span id="__span-93-5"><a id="__codelineno-93-5" name="__codelineno-93-5" href="#__codelineno-93-5"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-93-6"><a id="__codelineno-93-6" name="__codelineno-93-6" href="#__codelineno-93-6"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-93-7"><a id="__codelineno-93-7" name="__codelineno-93-7" href="#__codelineno-93-7"></a><span class="p">});</span>
</span></code></pre></div>
<p>In <code>admin/tsconfig.json</code>:</p>
<div class="language-json highlight"><pre><span></span><code><span id="__span-94-1"><a id="__codelineno-94-1" name="__codelineno-94-1" href="#__codelineno-94-1"></a><span class="p">{</span>
</span><span id="__span-94-2"><a id="__codelineno-94-2" name="__codelineno-94-2" href="#__codelineno-94-2"></a><span class="w"> </span><span class="nt">&quot;compilerOptions&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-94-3"><a id="__codelineno-94-3" name="__codelineno-94-3" href="#__codelineno-94-3"></a><span class="w"> </span><span class="nt">&quot;paths&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-94-4"><a id="__codelineno-94-4" name="__codelineno-94-4" href="#__codelineno-94-4"></a><span class="w"> </span><span class="nt">&quot;@/*&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;./src/*&quot;</span><span class="p">]</span>
</span><span id="__span-94-5"><a id="__codelineno-94-5" name="__codelineno-94-5" href="#__codelineno-94-5"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-94-6"><a id="__codelineno-94-6" name="__codelineno-94-6" href="#__codelineno-94-6"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-94-7"><a id="__codelineno-94-7" name="__codelineno-94-7" href="#__codelineno-94-7"></a><span class="p">}</span>
</span></code></pre></div>
<p><strong>Solution 4: Clear cache and reinstall</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-95-1"><a id="__codelineno-95-1" name="__codelineno-95-1" href="#__codelineno-95-1"></a><span class="nb">cd</span><span class="w"> </span>admin
</span><span id="__span-95-2"><a id="__codelineno-95-2" name="__codelineno-95-2" href="#__codelineno-95-2"></a>
</span><span id="__span-95-3"><a id="__codelineno-95-3" name="__codelineno-95-3" href="#__codelineno-95-3"></a><span class="c1"># Remove node_modules and lock file</span>
</span><span id="__span-95-4"><a id="__codelineno-95-4" name="__codelineno-95-4" href="#__codelineno-95-4"></a>rm<span class="w"> </span>-rf<span class="w"> </span>node_modules<span class="w"> </span>package-lock.json
</span><span id="__span-95-5"><a id="__codelineno-95-5" name="__codelineno-95-5" href="#__codelineno-95-5"></a>
</span><span id="__span-95-6"><a id="__codelineno-95-6" name="__codelineno-95-6" href="#__codelineno-95-6"></a><span class="c1"># Reinstall</span>
</span><span id="__span-95-7"><a id="__codelineno-95-7" name="__codelineno-95-7" href="#__codelineno-95-7"></a>npm<span class="w"> </span>install
</span><span id="__span-95-8"><a id="__codelineno-95-8" name="__codelineno-95-8" href="#__codelineno-95-8"></a>
</span><span id="__span-95-9"><a id="__codelineno-95-9" name="__codelineno-95-9" href="#__codelineno-95-9"></a><span class="c1"># Restart</span>
</span><span id="__span-95-10"><a id="__codelineno-95-10" name="__codelineno-95-10" href="#__codelineno-95-10"></a>npm<span class="w"> </span>run<span class="w"> </span>dev
</span></code></pre></div>
<h4 id="prevention_15">Prevention<a class="headerlink" href="#prevention_15" title="Permanent link">&para;</a></h4>
<ul>
<li><strong>Type checking</strong> - Use TypeScript for import validation</li>
<li><strong>IDE support</strong> - Configure path aliases in IDE</li>
<li><strong>Linting</strong> - Use ESLint with import plugin</li>
<li><strong>Documentation</strong> - Document custom path aliases</li>
</ul>
<hr />
<h3 id="hydration-errors">Hydration Errors<a class="headerlink" href="#hydration-errors" title="Permanent link">&para;</a></h3>
<p><strong>Severity:</strong> 🟡 Medium</p>
<h4 id="symptoms_16">Symptoms<a class="headerlink" href="#symptoms_16" title="Permanent link">&para;</a></h4>
<p>Browser console:
<div class="language-text highlight"><pre><span></span><code><span id="__span-96-1"><a id="__codelineno-96-1" name="__codelineno-96-1" href="#__codelineno-96-1"></a>Warning: Text content did not match. Server: &quot;...&quot; Client: &quot;...&quot;
</span></code></pre></div></p>
<p>Or:
<div class="language-text highlight"><pre><span></span><code><span id="__span-97-1"><a id="__codelineno-97-1" name="__codelineno-97-1" href="#__codelineno-97-1"></a>Error: Hydration failed because the initial UI does not match what was
</span><span id="__span-97-2"><a id="__codelineno-97-2" name="__codelineno-97-2" href="#__codelineno-97-2"></a>rendered on the server.
</span></code></pre></div></p>
<h4 id="common-causes_16">Common Causes<a class="headerlink" href="#common-causes_16" title="Permanent link">&para;</a></h4>
<ol>
<li><strong>Date formatting</strong> - Server/client timezone difference</li>
<li><strong>Random values</strong> - Using Math.random() or uuid</li>
<li><strong>localStorage</strong> - Reading from localStorage during render</li>
<li><strong>User agent</strong> - Checking window.navigator during SSR</li>
<li><strong>Third-party scripts</strong> - Injected by browser extensions</li>
</ol>
<h4 id="solutions_16">Solutions<a class="headerlink" href="#solutions_16" title="Permanent link">&para;</a></h4>
<p><strong>Solution 1: Use useEffect for client-only code</strong></p>
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-98-1"><a id="__codelineno-98-1" name="__codelineno-98-1" href="#__codelineno-98-1"></a><span class="c1">// Wrong:</span>
</span><span id="__span-98-2"><a id="__codelineno-98-2" name="__codelineno-98-2" href="#__codelineno-98-2"></a><span class="kd">const</span><span class="w"> </span><span class="nx">Component</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-98-3"><a id="__codelineno-98-3" name="__codelineno-98-3" href="#__codelineno-98-3"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">value</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">localStorage</span><span class="p">.</span><span class="nx">getItem</span><span class="p">(</span><span class="s1">&#39;key&#39;</span><span class="p">);</span>
</span><span id="__span-98-4"><a id="__codelineno-98-4" name="__codelineno-98-4" href="#__codelineno-98-4"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="o">&lt;</span><span class="nx">div</span><span class="o">&gt;</span><span class="p">{</span><span class="nx">value</span><span class="p">}</span><span class="o">&lt;</span><span class="err">/div&gt;;</span>
</span><span id="__span-98-5"><a id="__codelineno-98-5" name="__codelineno-98-5" href="#__codelineno-98-5"></a><span class="p">};</span>
</span><span id="__span-98-6"><a id="__codelineno-98-6" name="__codelineno-98-6" href="#__codelineno-98-6"></a>
</span><span id="__span-98-7"><a id="__codelineno-98-7" name="__codelineno-98-7" href="#__codelineno-98-7"></a><span class="c1">// Right:</span>
</span><span id="__span-98-8"><a id="__codelineno-98-8" name="__codelineno-98-8" href="#__codelineno-98-8"></a><span class="kd">const</span><span class="w"> </span><span class="nx">Component</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-98-9"><a id="__codelineno-98-9" name="__codelineno-98-9" href="#__codelineno-98-9"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">value</span><span class="p">,</span><span class="w"> </span><span class="nx">setValue</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">useState</span><span class="o">&lt;</span><span class="kt">string</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="kc">null</span><span class="o">&gt;</span><span class="p">(</span><span class="kc">null</span><span class="p">);</span>
</span><span id="__span-98-10"><a id="__codelineno-98-10" name="__codelineno-98-10" href="#__codelineno-98-10"></a>
</span><span id="__span-98-11"><a id="__codelineno-98-11" name="__codelineno-98-11" href="#__codelineno-98-11"></a><span class="w"> </span><span class="nx">useEffect</span><span class="p">(()</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-98-12"><a id="__codelineno-98-12" name="__codelineno-98-12" href="#__codelineno-98-12"></a><span class="w"> </span><span class="nx">setValue</span><span class="p">(</span><span class="nx">localStorage</span><span class="p">.</span><span class="nx">getItem</span><span class="p">(</span><span class="s1">&#39;key&#39;</span><span class="p">));</span>
</span><span id="__span-98-13"><a id="__codelineno-98-13" name="__codelineno-98-13" href="#__codelineno-98-13"></a><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">[]);</span>
</span><span id="__span-98-14"><a id="__codelineno-98-14" name="__codelineno-98-14" href="#__codelineno-98-14"></a>
</span><span id="__span-98-15"><a id="__codelineno-98-15" name="__codelineno-98-15" href="#__codelineno-98-15"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="o">&lt;</span><span class="nx">div</span><span class="o">&gt;</span><span class="p">{</span><span class="nx">value</span><span class="p">}</span><span class="o">&lt;</span><span class="err">/div&gt;;</span>
</span><span id="__span-98-16"><a id="__codelineno-98-16" name="__codelineno-98-16" href="#__codelineno-98-16"></a><span class="p">};</span>
</span></code></pre></div>
<p><strong>Solution 2: Consistent date formatting</strong></p>
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-99-1"><a id="__codelineno-99-1" name="__codelineno-99-1" href="#__codelineno-99-1"></a><span class="c1">// Wrong:</span>
</span><span id="__span-99-2"><a id="__codelineno-99-2" name="__codelineno-99-2" href="#__codelineno-99-2"></a><span class="o">&lt;</span><span class="nx">div</span><span class="o">&gt;</span><span class="p">{</span><span class="ow">new</span><span class="w"> </span><span class="nb">Date</span><span class="p">().</span><span class="nx">toLocaleString</span><span class="p">()}</span><span class="o">&lt;</span><span class="sr">/div&gt; /</span><span class="o">/</span><span class="w"> </span><span class="nx">Varies</span><span class="w"> </span><span class="nx">by</span><span class="w"> </span><span class="nx">locale</span>
</span><span id="__span-99-3"><a id="__codelineno-99-3" name="__codelineno-99-3" href="#__codelineno-99-3"></a>
</span><span id="__span-99-4"><a id="__codelineno-99-4" name="__codelineno-99-4" href="#__codelineno-99-4"></a><span class="c1">// Right:</span>
</span><span id="__span-99-5"><a id="__codelineno-99-5" name="__codelineno-99-5" href="#__codelineno-99-5"></a><span class="k">import</span><span class="w"> </span><span class="nx">dayjs</span><span class="w"> </span><span class="kr">from</span><span class="w"> </span><span class="s1">&#39;dayjs&#39;</span><span class="p">;</span>
</span><span id="__span-99-6"><a id="__codelineno-99-6" name="__codelineno-99-6" href="#__codelineno-99-6"></a><span class="o">&lt;</span><span class="nx">div</span><span class="o">&gt;</span><span class="p">{</span><span class="nx">dayjs</span><span class="p">().</span><span class="nx">format</span><span class="p">(</span><span class="s1">&#39;YYYY-MM-DD HH:mm:ss&#39;</span><span class="p">)}</span><span class="o">&lt;</span><span class="err">/div&gt;</span>
</span></code></pre></div>
<p><strong>Solution 3: suppressHydrationWarning for known mismatches</strong></p>
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-100-1"><a id="__codelineno-100-1" name="__codelineno-100-1" href="#__codelineno-100-1"></a><span class="c1">// For values that intentionally differ (like timestamps)</span>
</span><span id="__span-100-2"><a id="__codelineno-100-2" name="__codelineno-100-2" href="#__codelineno-100-2"></a><span class="o">&lt;</span><span class="nx">time</span><span class="w"> </span><span class="nx">suppressHydrationWarning</span><span class="o">&gt;</span>
</span><span id="__span-100-3"><a id="__codelineno-100-3" name="__codelineno-100-3" href="#__codelineno-100-3"></a><span class="w"> </span><span class="p">{</span><span class="ow">new</span><span class="w"> </span><span class="nb">Date</span><span class="p">().</span><span class="nx">toISOString</span><span class="p">()}</span>
</span><span id="__span-100-4"><a id="__codelineno-100-4" name="__codelineno-100-4" href="#__codelineno-100-4"></a><span class="o">&lt;</span><span class="err">/time&gt;</span>
</span></code></pre></div>
<p><strong>Solution 4: Check browser extensions</strong></p>
<p>Disable browser extensions temporarily to see if error persists.</p>
<h4 id="prevention_16">Prevention<a class="headerlink" href="#prevention_16" title="Permanent link">&para;</a></h4>
<ul>
<li><strong>Avoid client-only APIs during render</strong> - Use useEffect</li>
<li><strong>Consistent formatting</strong> - Same format server and client</li>
<li><strong>Test without extensions</strong> - Regular testing</li>
<li><strong>React DevTools</strong> - Use to identify mismatches</li>
</ul>
<div class="admonition note">
<p class="admonition-title">Changemaker Lite V2</p>
<p>Current admin is CSR (Client-Side Rendered) only, so hydration errors shouldn't occur. This section is for future SSR/SSG implementations.</p>
</div>
<hr />
<h2 id="file-upload-errors">File Upload Errors<a class="headerlink" href="#file-upload-errors" title="Permanent link">&para;</a></h2>
<h3 id="file-too-large">File Too Large<a class="headerlink" href="#file-too-large" title="Permanent link">&para;</a></h3>
<p><strong>Severity:</strong> 🟡 Medium</p>
<h4 id="symptoms_17">Symptoms<a class="headerlink" href="#symptoms_17" title="Permanent link">&para;</a></h4>
<div class="language-json highlight"><pre><span></span><code><span id="__span-101-1"><a id="__codelineno-101-1" name="__codelineno-101-1" href="#__codelineno-101-1"></a><span class="p">{</span>
</span><span id="__span-101-2"><a id="__codelineno-101-2" name="__codelineno-101-2" href="#__codelineno-101-2"></a><span class="w"> </span><span class="nt">&quot;error&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Payload Too Large&quot;</span><span class="p">,</span>
</span><span id="__span-101-3"><a id="__codelineno-101-3" name="__codelineno-101-3" href="#__codelineno-101-3"></a><span class="w"> </span><span class="nt">&quot;message&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;File size exceeds maximum of 10485760 bytes&quot;</span>
</span><span id="__span-101-4"><a id="__codelineno-101-4" name="__codelineno-101-4" href="#__codelineno-101-4"></a><span class="p">}</span>
</span></code></pre></div>
<p>Or browser:
<div class="language-text highlight"><pre><span></span><code><span id="__span-102-1"><a id="__codelineno-102-1" name="__codelineno-102-1" href="#__codelineno-102-1"></a>Request Entity Too Large
</span></code></pre></div></p>
<h4 id="common-causes_17">Common Causes<a class="headerlink" href="#common-causes_17" title="Permanent link">&para;</a></h4>
<ol>
<li><strong>File exceeds limit</strong> - Video larger than 10GB</li>
<li><strong>Nginx limit</strong> - Reverse proxy blocking</li>
<li><strong>Wrong content type</strong> - Not multipart/form-data</li>
<li><strong>Network timeout</strong> - Upload taking too long</li>
</ol>
<h4 id="solutions_17">Solutions<a class="headerlink" href="#solutions_17" title="Permanent link">&para;</a></h4>
<p><strong>Solution 1: Check file size</strong></p>
<div class="language-javascript highlight"><pre><span></span><code><span id="__span-103-1"><a id="__codelineno-103-1" name="__codelineno-103-1" href="#__codelineno-103-1"></a><span class="c1">// Before upload</span>
</span><span id="__span-103-2"><a id="__codelineno-103-2" name="__codelineno-103-2" href="#__codelineno-103-2"></a><span class="kd">const</span><span class="w"> </span><span class="nx">file</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">event</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">files</span><span class="p">[</span><span class="mf">0</span><span class="p">];</span>
</span><span id="__span-103-3"><a id="__codelineno-103-3" name="__codelineno-103-3" href="#__codelineno-103-3"></a><span class="kd">const</span><span class="w"> </span><span class="nx">maxSize</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">10</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mf">1024</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mf">1024</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mf">1024</span><span class="p">;</span><span class="w"> </span><span class="c1">// 10GB</span>
</span><span id="__span-103-4"><a id="__codelineno-103-4" name="__codelineno-103-4" href="#__codelineno-103-4"></a>
</span><span id="__span-103-5"><a id="__codelineno-103-5" name="__codelineno-103-5" href="#__codelineno-103-5"></a><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">file</span><span class="p">.</span><span class="nx">size</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="nx">maxSize</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-103-6"><a id="__codelineno-103-6" name="__codelineno-103-6" href="#__codelineno-103-6"></a><span class="w"> </span><span class="nx">alert</span><span class="p">(</span><span class="sb">`File too large. Max size: </span><span class="si">${</span><span class="nx">maxSize</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mf">1024</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mf">1024</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mf">1024</span><span class="si">}</span><span class="sb">GB`</span><span class="p">);</span>
</span><span id="__span-103-7"><a id="__codelineno-103-7" name="__codelineno-103-7" href="#__codelineno-103-7"></a><span class="w"> </span><span class="k">return</span><span class="p">;</span>
</span><span id="__span-103-8"><a id="__codelineno-103-8" name="__codelineno-103-8" href="#__codelineno-103-8"></a><span class="p">}</span>
</span></code></pre></div>
<p><strong>Solution 2: Increase limits</strong></p>
<p>In <code>api/src/modules/media/routes/upload.routes.ts</code>:</p>
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-104-1"><a id="__codelineno-104-1" name="__codelineno-104-1" href="#__codelineno-104-1"></a><span class="nx">fastify</span><span class="p">.</span><span class="nx">register</span><span class="p">(</span><span class="nx">multipart</span><span class="p">,</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-104-2"><a id="__codelineno-104-2" name="__codelineno-104-2" href="#__codelineno-104-2"></a><span class="w"> </span><span class="nx">limits</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-104-3"><a id="__codelineno-104-3" name="__codelineno-104-3" href="#__codelineno-104-3"></a><span class="w"> </span><span class="nx">fileSize</span><span class="o">:</span><span class="w"> </span><span class="kt">10</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mf">1024</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mf">1024</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mf">1024</span><span class="w"> </span><span class="c1">// 10GB</span>
</span><span id="__span-104-4"><a id="__codelineno-104-4" name="__codelineno-104-4" href="#__codelineno-104-4"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-104-5"><a id="__codelineno-104-5" name="__codelineno-104-5" href="#__codelineno-104-5"></a><span class="p">});</span>
</span></code></pre></div>
<p>In <code>nginx/conf.d/api.conf</code>:</p>
<div class="language-nginx highlight"><pre><span></span><code><span id="__span-105-1"><a id="__codelineno-105-1" name="__codelineno-105-1" href="#__codelineno-105-1"></a><span class="k">client_max_body_size</span><span class="w"> </span><span class="s">10G</span><span class="p">;</span>
</span></code></pre></div>
<p><strong>Solution 3: Use chunked upload</strong></p>
<p>For very large files, implement resumable upload:</p>
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-106-1"><a id="__codelineno-106-1" name="__codelineno-106-1" href="#__codelineno-106-1"></a><span class="c1">// TODO: Implement chunked upload in Phase 15</span>
</span></code></pre></div>
<p><strong>Solution 4: Compress video</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-107-1"><a id="__codelineno-107-1" name="__codelineno-107-1" href="#__codelineno-107-1"></a><span class="c1"># Before uploading, compress with ffmpeg</span>
</span><span id="__span-107-2"><a id="__codelineno-107-2" name="__codelineno-107-2" href="#__codelineno-107-2"></a>ffmpeg<span class="w"> </span>-i<span class="w"> </span>input.mp4<span class="w"> </span>-c:v<span class="w"> </span>libx264<span class="w"> </span>-crf<span class="w"> </span><span class="m">23</span><span class="w"> </span>-c:a<span class="w"> </span>aac<span class="w"> </span>output.mp4
</span></code></pre></div>
<h4 id="prevention_17">Prevention<a class="headerlink" href="#prevention_17" title="Permanent link">&para;</a></h4>
<ul>
<li><strong>Client validation</strong> - Check size before upload</li>
<li><strong>Progress indicator</strong> - Show upload progress</li>
<li><strong>Compression</strong> - Compress large videos</li>
<li><strong>Chunked uploads</strong> - For files &gt; 1GB</li>
</ul>
<hr />
<h3 id="invalid-file-type">Invalid File Type<a class="headerlink" href="#invalid-file-type" title="Permanent link">&para;</a></h3>
<p><strong>Severity:</strong> 🟢 Low</p>
<h4 id="symptoms_18">Symptoms<a class="headerlink" href="#symptoms_18" title="Permanent link">&para;</a></h4>
<div class="language-json highlight"><pre><span></span><code><span id="__span-108-1"><a id="__codelineno-108-1" name="__codelineno-108-1" href="#__codelineno-108-1"></a><span class="p">{</span>
</span><span id="__span-108-2"><a id="__codelineno-108-2" name="__codelineno-108-2" href="#__codelineno-108-2"></a><span class="w"> </span><span class="nt">&quot;error&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Bad Request&quot;</span><span class="p">,</span>
</span><span id="__span-108-3"><a id="__codelineno-108-3" name="__codelineno-108-3" href="#__codelineno-108-3"></a><span class="w"> </span><span class="nt">&quot;message&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Invalid file type. Allowed: mp4, mov, avi, mkv, webm, m4v, flv&quot;</span>
</span><span id="__span-108-4"><a id="__codelineno-108-4" name="__codelineno-108-4" href="#__codelineno-108-4"></a><span class="p">}</span>
</span></code></pre></div>
<h4 id="common-causes_18">Common Causes<a class="headerlink" href="#common-causes_18" title="Permanent link">&para;</a></h4>
<ol>
<li><strong>Wrong extension</strong> - File has unsupported extension</li>
<li><strong>Missing extension</strong> - Filename has no extension</li>
<li><strong>Mismatched extension</strong> - Extension doesn't match content</li>
<li><strong>MIME type issue</strong> - Browser sends wrong MIME type</li>
</ol>
<h4 id="solutions_18">Solutions<a class="headerlink" href="#solutions_18" title="Permanent link">&para;</a></h4>
<p><strong>Solution 1: Check supported formats</strong></p>
<p>Supported video formats:</p>
<ul>
<li>MP4 (.mp4)</li>
<li>MOV (.mov)</li>
<li>AVI (.avi)</li>
<li>MKV (.mkv)</li>
<li>WebM (.webm)</li>
<li>M4V (.m4v)</li>
<li>FLV (.flv)</li>
</ul>
<p><strong>Solution 2: Convert video</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-109-1"><a id="__codelineno-109-1" name="__codelineno-109-1" href="#__codelineno-109-1"></a><span class="c1"># Convert to MP4 (most compatible)</span>
</span><span id="__span-109-2"><a id="__codelineno-109-2" name="__codelineno-109-2" href="#__codelineno-109-2"></a>ffmpeg<span class="w"> </span>-i<span class="w"> </span>input.avi<span class="w"> </span>-c:v<span class="w"> </span>libx264<span class="w"> </span>-c:a<span class="w"> </span>aac<span class="w"> </span>output.mp4
</span></code></pre></div>
<p><strong>Solution 3: Check file extension</strong></p>
<div class="language-javascript highlight"><pre><span></span><code><span id="__span-110-1"><a id="__codelineno-110-1" name="__codelineno-110-1" href="#__codelineno-110-1"></a><span class="kd">const</span><span class="w"> </span><span class="nx">file</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">event</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">files</span><span class="p">[</span><span class="mf">0</span><span class="p">];</span>
</span><span id="__span-110-2"><a id="__codelineno-110-2" name="__codelineno-110-2" href="#__codelineno-110-2"></a><span class="kd">const</span><span class="w"> </span><span class="nx">ext</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">file</span><span class="p">.</span><span class="nx">name</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">&#39;.&#39;</span><span class="p">).</span><span class="nx">pop</span><span class="p">().</span><span class="nx">toLowerCase</span><span class="p">();</span>
</span><span id="__span-110-3"><a id="__codelineno-110-3" name="__codelineno-110-3" href="#__codelineno-110-3"></a><span class="kd">const</span><span class="w"> </span><span class="nx">allowed</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s1">&#39;mp4&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;mov&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;avi&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;mkv&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;webm&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;m4v&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;flv&#39;</span><span class="p">];</span>
</span><span id="__span-110-4"><a id="__codelineno-110-4" name="__codelineno-110-4" href="#__codelineno-110-4"></a>
</span><span id="__span-110-5"><a id="__codelineno-110-5" name="__codelineno-110-5" href="#__codelineno-110-5"></a><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">allowed</span><span class="p">.</span><span class="nx">includes</span><span class="p">(</span><span class="nx">ext</span><span class="p">))</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-110-6"><a id="__codelineno-110-6" name="__codelineno-110-6" href="#__codelineno-110-6"></a><span class="w"> </span><span class="nx">alert</span><span class="p">(</span><span class="sb">`Invalid file type: .</span><span class="si">${</span><span class="nx">ext</span><span class="si">}</span><span class="sb">`</span><span class="p">);</span>
</span><span id="__span-110-7"><a id="__codelineno-110-7" name="__codelineno-110-7" href="#__codelineno-110-7"></a><span class="w"> </span><span class="k">return</span><span class="p">;</span>
</span><span id="__span-110-8"><a id="__codelineno-110-8" name="__codelineno-110-8" href="#__codelineno-110-8"></a><span class="p">}</span>
</span></code></pre></div>
<p><strong>Solution 4: Verify with file command</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-111-1"><a id="__codelineno-111-1" name="__codelineno-111-1" href="#__codelineno-111-1"></a><span class="c1"># Check actual file type</span>
</span><span id="__span-111-2"><a id="__codelineno-111-2" name="__codelineno-111-2" href="#__codelineno-111-2"></a>file<span class="w"> </span>video.mp4
</span><span id="__span-111-3"><a id="__codelineno-111-3" name="__codelineno-111-3" href="#__codelineno-111-3"></a>
</span><span id="__span-111-4"><a id="__codelineno-111-4" name="__codelineno-111-4" href="#__codelineno-111-4"></a><span class="c1"># Should show:</span>
</span><span id="__span-111-5"><a id="__codelineno-111-5" name="__codelineno-111-5" href="#__codelineno-111-5"></a><span class="c1"># video.mp4: ISO Media, MP4 v2 [ISO 14496-14]</span>
</span></code></pre></div>
<h4 id="prevention_18">Prevention<a class="headerlink" href="#prevention_18" title="Permanent link">&para;</a></h4>
<ul>
<li><strong>Client validation</strong> - Check extension before upload</li>
<li><strong>MIME type checking</strong> - Validate content type</li>
<li><strong>File magic numbers</strong> - Check file signature</li>
<li><strong>Clear documentation</strong> - List supported formats</li>
</ul>
<hr />
<h3 id="upload-timeout">Upload Timeout<a class="headerlink" href="#upload-timeout" title="Permanent link">&para;</a></h3>
<p><strong>Severity:</strong> 🟡 Medium</p>
<h4 id="symptoms_19">Symptoms<a class="headerlink" href="#symptoms_19" title="Permanent link">&para;</a></h4>
<div class="language-text highlight"><pre><span></span><code><span id="__span-112-1"><a id="__codelineno-112-1" name="__codelineno-112-1" href="#__codelineno-112-1"></a>Error: timeout of 30000ms exceeded
</span></code></pre></div>
<p>Or:
<div class="language-text highlight"><pre><span></span><code><span id="__span-113-1"><a id="__codelineno-113-1" name="__codelineno-113-1" href="#__codelineno-113-1"></a>504 Gateway Timeout
</span></code></pre></div></p>
<h4 id="common-causes_19">Common Causes<a class="headerlink" href="#common-causes_19" title="Permanent link">&para;</a></h4>
<ol>
<li><strong>Slow network</strong> - Large file, slow connection</li>
<li><strong>Server timeout</strong> - Request timeout too short</li>
<li><strong>Processing delay</strong> - FFprobe taking too long</li>
<li><strong>Network interruption</strong> - Connection dropped</li>
</ol>
<h4 id="solutions_19">Solutions<a class="headerlink" href="#solutions_19" title="Permanent link">&para;</a></h4>
<p><strong>Solution 1: Increase timeout</strong></p>
<p>In <code>admin/src/lib/media-api.ts</code>:</p>
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-114-1"><a id="__codelineno-114-1" name="__codelineno-114-1" href="#__codelineno-114-1"></a><span class="k">export</span><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">mediaApi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">axios</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
</span><span id="__span-114-2"><a id="__codelineno-114-2" name="__codelineno-114-2" href="#__codelineno-114-2"></a><span class="w"> </span><span class="nx">baseURL</span><span class="o">:</span><span class="w"> </span><span class="kt">import.meta.env.VITE_MEDIA_API_URL</span><span class="p">,</span>
</span><span id="__span-114-3"><a id="__codelineno-114-3" name="__codelineno-114-3" href="#__codelineno-114-3"></a><span class="w"> </span><span class="nx">timeout</span><span class="o">:</span><span class="w"> </span><span class="kt">300000</span><span class="w"> </span><span class="c1">// 5 minutes instead of 30 seconds</span>
</span><span id="__span-114-4"><a id="__codelineno-114-4" name="__codelineno-114-4" href="#__codelineno-114-4"></a><span class="p">});</span>
</span></code></pre></div>
<p><strong>Solution 2: Check upload progress</strong></p>
<div class="language-javascript highlight"><pre><span></span><code><span id="__span-115-1"><a id="__codelineno-115-1" name="__codelineno-115-1" href="#__codelineno-115-1"></a><span class="k">await</span><span class="w"> </span><span class="nx">mediaApi</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="s1">&#39;/upload&#39;</span><span class="p">,</span><span class="w"> </span><span class="nx">formData</span><span class="p">,</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-115-2"><a id="__codelineno-115-2" name="__codelineno-115-2" href="#__codelineno-115-2"></a><span class="w"> </span><span class="nx">onUploadProgress</span><span class="o">:</span><span class="w"> </span><span class="p">(</span><span class="nx">progressEvent</span><span class="p">)</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-115-3"><a id="__codelineno-115-3" name="__codelineno-115-3" href="#__codelineno-115-3"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">percent</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="nx">progressEvent</span><span class="p">.</span><span class="nx">loaded</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="nx">progressEvent</span><span class="p">.</span><span class="nx">total</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mf">100</span><span class="p">;</span>
</span><span id="__span-115-4"><a id="__codelineno-115-4" name="__codelineno-115-4" href="#__codelineno-115-4"></a><span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="sb">`Upload: </span><span class="si">${</span><span class="nx">percent</span><span class="p">.</span><span class="nx">toFixed</span><span class="p">(</span><span class="mf">2</span><span class="p">)</span><span class="si">}</span><span class="sb">%`</span><span class="p">);</span>
</span><span id="__span-115-5"><a id="__codelineno-115-5" name="__codelineno-115-5" href="#__codelineno-115-5"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-115-6"><a id="__codelineno-115-6" name="__codelineno-115-6" href="#__codelineno-115-6"></a><span class="p">});</span>
</span></code></pre></div>
<p><strong>Solution 3: Increase nginx timeout</strong></p>
<p>In <code>nginx/conf.d/api.conf</code>:</p>
<div class="language-nginx highlight"><pre><span></span><code><span id="__span-116-1"><a id="__codelineno-116-1" name="__codelineno-116-1" href="#__codelineno-116-1"></a><span class="k">proxy_read_timeout</span><span class="w"> </span><span class="s">300s</span><span class="p">;</span>
</span><span id="__span-116-2"><a id="__codelineno-116-2" name="__codelineno-116-2" href="#__codelineno-116-2"></a><span class="k">proxy_connect_timeout</span><span class="w"> </span><span class="s">300s</span><span class="p">;</span>
</span><span id="__span-116-3"><a id="__codelineno-116-3" name="__codelineno-116-3" href="#__codelineno-116-3"></a><span class="k">proxy_send_timeout</span><span class="w"> </span><span class="s">300s</span><span class="p">;</span>
</span></code></pre></div>
<p><strong>Solution 4: Upload via chunks</strong></p>
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-117-1"><a id="__codelineno-117-1" name="__codelineno-117-1" href="#__codelineno-117-1"></a><span class="c1">// TODO: Implement chunked upload for large files</span>
</span></code></pre></div>
<h4 id="prevention_19">Prevention<a class="headerlink" href="#prevention_19" title="Permanent link">&para;</a></h4>
<ul>
<li><strong>Progress indicator</strong> - Show upload progress</li>
<li><strong>Generous timeouts</strong> - Allow enough time for large files</li>
<li><strong>Retry logic</strong> - Auto-retry on network errors</li>
<li><strong>Chunked uploads</strong> - For files &gt; 1GB</li>
</ul>
<hr />
<h2 id="email-errors">Email Errors<a class="headerlink" href="#email-errors" title="Permanent link">&para;</a></h2>
<h3 id="smtp-connection-failed">SMTP Connection Failed<a class="headerlink" href="#smtp-connection-failed" title="Permanent link">&para;</a></h3>
<p><strong>Severity:</strong> 🔴 Critical</p>
<h4 id="symptoms_20">Symptoms<a class="headerlink" href="#symptoms_20" title="Permanent link">&para;</a></h4>
<p>API logs:
<div class="language-text highlight"><pre><span></span><code><span id="__span-118-1"><a id="__codelineno-118-1" name="__codelineno-118-1" href="#__codelineno-118-1"></a>Error: Connection timeout
</span><span id="__span-118-2"><a id="__codelineno-118-2" name="__codelineno-118-2" href="#__codelineno-118-2"></a>Error: connect ECONNREFUSED 127.0.0.1:587
</span></code></pre></div></p>
<p>Or:
<div class="language-text highlight"><pre><span></span><code><span id="__span-119-1"><a id="__codelineno-119-1" name="__codelineno-119-1" href="#__codelineno-119-1"></a>Error: Invalid login: 535-5.7.8 Username and Password not accepted
</span></code></pre></div></p>
<h4 id="common-causes_20">Common Causes<a class="headerlink" href="#common-causes_20" title="Permanent link">&para;</a></h4>
<ol>
<li><strong>SMTP server down</strong> - Mail server unreachable</li>
<li><strong>Wrong credentials</strong> - Invalid username/password</li>
<li><strong>Port blocked</strong> - Firewall blocking SMTP port</li>
<li><strong>TLS/SSL issue</strong> - Certificate validation failed</li>
</ol>
<h4 id="solutions_20">Solutions<a class="headerlink" href="#solutions_20" title="Permanent link">&para;</a></h4>
<p><strong>Solution 1: Test SMTP connection</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-120-1"><a id="__codelineno-120-1" name="__codelineno-120-1" href="#__codelineno-120-1"></a><span class="c1"># Test with telnet</span>
</span><span id="__span-120-2"><a id="__codelineno-120-2" name="__codelineno-120-2" href="#__codelineno-120-2"></a>telnet<span class="w"> </span>smtp.gmail.com<span class="w"> </span><span class="m">587</span>
</span><span id="__span-120-3"><a id="__codelineno-120-3" name="__codelineno-120-3" href="#__codelineno-120-3"></a>
</span><span id="__span-120-4"><a id="__codelineno-120-4" name="__codelineno-120-4" href="#__codelineno-120-4"></a><span class="c1"># Should connect and show:</span>
</span><span id="__span-120-5"><a id="__codelineno-120-5" name="__codelineno-120-5" href="#__codelineno-120-5"></a><span class="c1"># 220 smtp.gmail.com ESMTP...</span>
</span></code></pre></div>
<p><strong>Solution 2: Verify SMTP configuration</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-121-1"><a id="__codelineno-121-1" name="__codelineno-121-1" href="#__codelineno-121-1"></a><span class="c1"># Check .env</span>
</span><span id="__span-121-2"><a id="__codelineno-121-2" name="__codelineno-121-2" href="#__codelineno-121-2"></a>cat<span class="w"> </span>.env<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>SMTP
</span><span id="__span-121-3"><a id="__codelineno-121-3" name="__codelineno-121-3" href="#__codelineno-121-3"></a>
</span><span id="__span-121-4"><a id="__codelineno-121-4" name="__codelineno-121-4" href="#__codelineno-121-4"></a><span class="c1"># Required settings:</span>
</span><span id="__span-121-5"><a id="__codelineno-121-5" name="__codelineno-121-5" href="#__codelineno-121-5"></a><span class="nv">SMTP_HOST</span><span class="o">=</span>smtp.gmail.com
</span><span id="__span-121-6"><a id="__codelineno-121-6" name="__codelineno-121-6" href="#__codelineno-121-6"></a><span class="nv">SMTP_PORT</span><span class="o">=</span><span class="m">587</span>
</span><span id="__span-121-7"><a id="__codelineno-121-7" name="__codelineno-121-7" href="#__codelineno-121-7"></a><span class="nv">SMTP_SECURE</span><span class="o">=</span><span class="nb">false</span>
</span><span id="__span-121-8"><a id="__codelineno-121-8" name="__codelineno-121-8" href="#__codelineno-121-8"></a><span class="nv">SMTP_USER</span><span class="o">=</span>your-email@gmail.com
</span><span id="__span-121-9"><a id="__codelineno-121-9" name="__codelineno-121-9" href="#__codelineno-121-9"></a><span class="nv">SMTP_PASS</span><span class="o">=</span>your-app-password
</span><span id="__span-121-10"><a id="__codelineno-121-10" name="__codelineno-121-10" href="#__codelineno-121-10"></a><span class="nv">SMTP_FROM</span><span class="o">=</span>your-email@gmail.com
</span></code></pre></div>
<p><strong>Solution 3: Use test mode</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-122-1"><a id="__codelineno-122-1" name="__codelineno-122-1" href="#__codelineno-122-1"></a><span class="c1"># In .env</span>
</span><span id="__span-122-2"><a id="__codelineno-122-2" name="__codelineno-122-2" href="#__codelineno-122-2"></a><span class="nv">EMAIL_TEST_MODE</span><span class="o">=</span><span class="nb">true</span>
</span><span id="__span-122-3"><a id="__codelineno-122-3" name="__codelineno-122-3" href="#__codelineno-122-3"></a>
</span><span id="__span-122-4"><a id="__codelineno-122-4" name="__codelineno-122-4" href="#__codelineno-122-4"></a><span class="c1"># Restart API</span>
</span><span id="__span-122-5"><a id="__codelineno-122-5" name="__codelineno-122-5" href="#__codelineno-122-5"></a>docker<span class="w"> </span>compose<span class="w"> </span>restart<span class="w"> </span>api
</span><span id="__span-122-6"><a id="__codelineno-122-6" name="__codelineno-122-6" href="#__codelineno-122-6"></a>
</span><span id="__span-122-7"><a id="__codelineno-122-7" name="__codelineno-122-7" href="#__codelineno-122-7"></a><span class="c1"># Emails now sent to MailHog (http://localhost:8025)</span>
</span></code></pre></div>
<p><strong>Solution 4: Check Gmail app password</strong></p>
<p>For Gmail:</p>
<ol>
<li>Enable 2-factor authentication</li>
<li>Generate app password at https://myaccount.google.com/apppasswords</li>
<li>Use app password (not regular password) in SMTP_PASS</li>
</ol>
<p><strong>Solution 5: Test with curl</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-123-1"><a id="__codelineno-123-1" name="__codelineno-123-1" href="#__codelineno-123-1"></a><span class="c1"># Send test email via API</span>
</span><span id="__span-123-2"><a id="__codelineno-123-2" name="__codelineno-123-2" href="#__codelineno-123-2"></a>curl<span class="w"> </span>-X<span class="w"> </span>POST<span class="w"> </span>http://localhost:4000/api/test-email<span class="w"> </span><span class="se">\</span>
</span><span id="__span-123-3"><a id="__codelineno-123-3" name="__codelineno-123-3" href="#__codelineno-123-3"></a><span class="w"> </span>-H<span class="w"> </span><span class="s2">&quot;Content-Type: application/json&quot;</span><span class="w"> </span><span class="se">\</span>
</span><span id="__span-123-4"><a id="__codelineno-123-4" name="__codelineno-123-4" href="#__codelineno-123-4"></a><span class="w"> </span>-H<span class="w"> </span><span class="s2">&quot;Authorization: Bearer YOUR_TOKEN&quot;</span><span class="w"> </span><span class="se">\</span>
</span><span id="__span-123-5"><a id="__codelineno-123-5" name="__codelineno-123-5" href="#__codelineno-123-5"></a><span class="w"> </span>-d<span class="w"> </span><span class="s1">&#39;{</span>
</span><span id="__span-123-6"><a id="__codelineno-123-6" name="__codelineno-123-6" href="#__codelineno-123-6"></a><span class="s1"> &quot;to&quot;: &quot;test@example.com&quot;,</span>
</span><span id="__span-123-7"><a id="__codelineno-123-7" name="__codelineno-123-7" href="#__codelineno-123-7"></a><span class="s1"> &quot;subject&quot;: &quot;Test Email&quot;,</span>
</span><span id="__span-123-8"><a id="__codelineno-123-8" name="__codelineno-123-8" href="#__codelineno-123-8"></a><span class="s1"> &quot;text&quot;: &quot;This is a test&quot;</span>
</span><span id="__span-123-9"><a id="__codelineno-123-9" name="__codelineno-123-9" href="#__codelineno-123-9"></a><span class="s1"> }&#39;</span>
</span></code></pre></div>
<h4 id="prevention_20">Prevention<a class="headerlink" href="#prevention_20" title="Permanent link">&para;</a></h4>
<ul>
<li><strong>Test mode for dev</strong> - Use MailHog locally</li>
<li><strong>Monitor SMTP health</strong> - Alert on connection failures</li>
<li><strong>Fallback providers</strong> - Configure backup SMTP server</li>
<li><strong>Queue system</strong> - BullMQ retries failed emails</li>
</ul>
<hr />
<h3 id="template-not-found">Template Not Found<a class="headerlink" href="#template-not-found" title="Permanent link">&para;</a></h3>
<p><strong>Severity:</strong> 🟠 High</p>
<h4 id="symptoms_21">Symptoms<a class="headerlink" href="#symptoms_21" title="Permanent link">&para;</a></h4>
<p>API logs:
<div class="language-text highlight"><pre><span></span><code><span id="__span-124-1"><a id="__codelineno-124-1" name="__codelineno-124-1" href="#__codelineno-124-1"></a>Error: Email template not found: campaign-email
</span></code></pre></div></p>
<p>Or:
<div class="language-text highlight"><pre><span></span><code><span id="__span-125-1"><a id="__codelineno-125-1" name="__codelineno-125-1" href="#__codelineno-125-1"></a>Error: ENOENT: no such file or directory, open &#39;templates/campaign-email.html&#39;
</span></code></pre></div></p>
<h4 id="common-causes_21">Common Causes<a class="headerlink" href="#common-causes_21" title="Permanent link">&para;</a></h4>
<ol>
<li><strong>Missing template file</strong> - Template not created</li>
<li><strong>Wrong template name</strong> - Typo in template name</li>
<li><strong>Wrong path</strong> - Looking in wrong directory</li>
<li><strong>Deleted template</strong> - Template was removed</li>
</ol>
<h4 id="solutions_21">Solutions<a class="headerlink" href="#solutions_21" title="Permanent link">&para;</a></h4>
<p><strong>Solution 1: Check template exists</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-126-1"><a id="__codelineno-126-1" name="__codelineno-126-1" href="#__codelineno-126-1"></a><span class="c1"># List all templates</span>
</span><span id="__span-126-2"><a id="__codelineno-126-2" name="__codelineno-126-2" href="#__codelineno-126-2"></a>docker<span class="w"> </span>compose<span class="w"> </span><span class="nb">exec</span><span class="w"> </span>api<span class="w"> </span>ls<span class="w"> </span>-la<span class="w"> </span>templates/
</span><span id="__span-126-3"><a id="__codelineno-126-3" name="__codelineno-126-3" href="#__codelineno-126-3"></a>
</span><span id="__span-126-4"><a id="__codelineno-126-4" name="__codelineno-126-4" href="#__codelineno-126-4"></a><span class="c1"># Should show:</span>
</span><span id="__span-126-5"><a id="__codelineno-126-5" name="__codelineno-126-5" href="#__codelineno-126-5"></a><span class="c1"># campaign-email.html</span>
</span><span id="__span-126-6"><a id="__codelineno-126-6" name="__codelineno-126-6" href="#__codelineno-126-6"></a><span class="c1"># shift-confirmation.html</span>
</span><span id="__span-126-7"><a id="__codelineno-126-7" name="__codelineno-126-7" href="#__codelineno-126-7"></a><span class="c1"># verification-email.html</span>
</span><span id="__span-126-8"><a id="__codelineno-126-8" name="__codelineno-126-8" href="#__codelineno-126-8"></a><span class="c1"># etc.</span>
</span></code></pre></div>
<p><strong>Solution 2: Verify template name</strong></p>
<p>In <code>api/src/services/email.service.ts</code>:</p>
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-127-1"><a id="__codelineno-127-1" name="__codelineno-127-1" href="#__codelineno-127-1"></a><span class="c1">// Template names must match filenames (without .html)</span>
</span><span id="__span-127-2"><a id="__codelineno-127-2" name="__codelineno-127-2" href="#__codelineno-127-2"></a><span class="k">await</span><span class="w"> </span><span class="nx">emailService</span><span class="p">.</span><span class="nx">sendEmail</span><span class="p">({</span>
</span><span id="__span-127-3"><a id="__codelineno-127-3" name="__codelineno-127-3" href="#__codelineno-127-3"></a><span class="w"> </span><span class="nx">to</span><span class="o">:</span><span class="w"> </span><span class="kt">email</span><span class="p">,</span>
</span><span id="__span-127-4"><a id="__codelineno-127-4" name="__codelineno-127-4" href="#__codelineno-127-4"></a><span class="w"> </span><span class="nx">subject</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;Campaign Email&#39;</span><span class="p">,</span>
</span><span id="__span-127-5"><a id="__codelineno-127-5" name="__codelineno-127-5" href="#__codelineno-127-5"></a><span class="w"> </span><span class="nx">template</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;campaign-email&#39;</span><span class="p">,</span><span class="w"> </span><span class="c1">// Looks for templates/campaign-email.html</span>
</span><span id="__span-127-6"><a id="__codelineno-127-6" name="__codelineno-127-6" href="#__codelineno-127-6"></a><span class="w"> </span><span class="nx">variables</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">...</span><span class="w"> </span><span class="p">}</span>
</span><span id="__span-127-7"><a id="__codelineno-127-7" name="__codelineno-127-7" href="#__codelineno-127-7"></a><span class="p">});</span>
</span></code></pre></div>
<p><strong>Solution 3: Create missing template</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-128-1"><a id="__codelineno-128-1" name="__codelineno-128-1" href="#__codelineno-128-1"></a><span class="c1"># Create template</span>
</span><span id="__span-128-2"><a id="__codelineno-128-2" name="__codelineno-128-2" href="#__codelineno-128-2"></a>docker<span class="w"> </span>compose<span class="w"> </span><span class="nb">exec</span><span class="w"> </span>api<span class="w"> </span>sh<span class="w"> </span>-c<span class="w"> </span><span class="s1">&#39;cat &gt; templates/my-template.html &lt;&lt; EOF</span>
</span><span id="__span-128-3"><a id="__codelineno-128-3" name="__codelineno-128-3" href="#__codelineno-128-3"></a><span class="s1">&lt;!DOCTYPE html&gt;</span>
</span><span id="__span-128-4"><a id="__codelineno-128-4" name="__codelineno-128-4" href="#__codelineno-128-4"></a><span class="s1">&lt;html&gt;</span>
</span><span id="__span-128-5"><a id="__codelineno-128-5" name="__codelineno-128-5" href="#__codelineno-128-5"></a><span class="s1">&lt;body&gt;</span>
</span><span id="__span-128-6"><a id="__codelineno-128-6" name="__codelineno-128-6" href="#__codelineno-128-6"></a><span class="s1"> &lt;h1&gt;Hello {{name}}&lt;/h1&gt;</span>
</span><span id="__span-128-7"><a id="__codelineno-128-7" name="__codelineno-128-7" href="#__codelineno-128-7"></a><span class="s1"> &lt;p&gt;{{message}}&lt;/p&gt;</span>
</span><span id="__span-128-8"><a id="__codelineno-128-8" name="__codelineno-128-8" href="#__codelineno-128-8"></a><span class="s1">&lt;/body&gt;</span>
</span><span id="__span-128-9"><a id="__codelineno-128-9" name="__codelineno-128-9" href="#__codelineno-128-9"></a><span class="s1">&lt;/html&gt;</span>
</span><span id="__span-128-10"><a id="__codelineno-128-10" name="__codelineno-128-10" href="#__codelineno-128-10"></a><span class="s1">EOF&#39;</span>
</span></code></pre></div>
<p><strong>Solution 4: Use email template system</strong></p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-129-1"><a id="__codelineno-129-1" name="__codelineno-129-1" href="#__codelineno-129-1"></a><span class="c1"># Navigate to admin UI</span>
</span><span id="__span-129-2"><a id="__codelineno-129-2" name="__codelineno-129-2" href="#__codelineno-129-2"></a>http://localhost:3000/app/email-templates
</span><span id="__span-129-3"><a id="__codelineno-129-3" name="__codelineno-129-3" href="#__codelineno-129-3"></a>
</span><span id="__span-129-4"><a id="__codelineno-129-4" name="__codelineno-129-4" href="#__codelineno-129-4"></a><span class="c1"># Create template there (saved to database + file)</span>
</span></code></pre></div>
<h4 id="prevention_21">Prevention<a class="headerlink" href="#prevention_21" title="Permanent link">&para;</a></h4>
<ul>
<li><strong>Seed templates</strong> - Include in database seed</li>
<li><strong>Template management</strong> - Use admin UI to manage</li>
<li><strong>Version control</strong> - Keep templates in git</li>
<li><strong>Validation</strong> - Check template exists before sending</li>
</ul>
<hr />
<h3 id="variable-missing">Variable Missing<a class="headerlink" href="#variable-missing" title="Permanent link">&para;</a></h3>
<p><strong>Severity:</strong> 🟡 Medium</p>
<h4 id="symptoms_22">Symptoms<a class="headerlink" href="#symptoms_22" title="Permanent link">&para;</a></h4>
<p>Email received with placeholders not replaced:
<div class="language-text highlight"><pre><span></span><code><span id="__span-130-1"><a id="__codelineno-130-1" name="__codelineno-130-1" href="#__codelineno-130-1"></a>Hello {{name}},
</span><span id="__span-130-2"><a id="__codelineno-130-2" name="__codelineno-130-2" href="#__codelineno-130-2"></a>Your campaign {{campaignName}} is ready.
</span></code></pre></div></p>
<p>Or API logs:
<div class="language-text highlight"><pre><span></span><code><span id="__span-131-1"><a id="__codelineno-131-1" name="__codelineno-131-1" href="#__codelineno-131-1"></a>Warning: Template variable &#39;campaignName&#39; not provided
</span></code></pre></div></p>
<h4 id="common-causes_22">Common Causes<a class="headerlink" href="#common-causes_22" title="Permanent link">&para;</a></h4>
<ol>
<li><strong>Variable not passed</strong> - Missing from variables object</li>
<li><strong>Variable name mismatch</strong> - Typo in variable name</li>
<li><strong>Wrong template</strong> - Using wrong template</li>
<li><strong>Case sensitivity</strong> - Variable name case mismatch</li>
</ol>
<h4 id="solutions_22">Solutions<a class="headerlink" href="#solutions_22" title="Permanent link">&para;</a></h4>
<p><strong>Solution 1: Check template variables</strong></p>
<p>In template file:</p>
<div class="language-html highlight"><pre><span></span><code><span id="__span-132-1"><a id="__codelineno-132-1" name="__codelineno-132-1" href="#__codelineno-132-1"></a><span class="cm">&lt;!-- templates/campaign-email.html --&gt;</span>
</span><span id="__span-132-2"><a id="__codelineno-132-2" name="__codelineno-132-2" href="#__codelineno-132-2"></a><span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span>Hello {{firstName}}<span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
</span><span id="__span-132-3"><a id="__codelineno-132-3" name="__codelineno-132-3" href="#__codelineno-132-3"></a><span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>Your campaign &quot;{{campaignName}}&quot; is ready.<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span><span id="__span-132-4"><a id="__codelineno-132-4" name="__codelineno-132-4" href="#__codelineno-132-4"></a><span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>Visit: {{campaignUrl}}<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></code></pre></div>
<p><strong>Solution 2: Provide all variables</strong></p>
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-133-1"><a id="__codelineno-133-1" name="__codelineno-133-1" href="#__codelineno-133-1"></a><span class="k">await</span><span class="w"> </span><span class="nx">emailService</span><span class="p">.</span><span class="nx">sendEmail</span><span class="p">({</span>
</span><span id="__span-133-2"><a id="__codelineno-133-2" name="__codelineno-133-2" href="#__codelineno-133-2"></a><span class="w"> </span><span class="nx">to</span><span class="o">:</span><span class="w"> </span><span class="kt">email</span><span class="p">,</span>
</span><span id="__span-133-3"><a id="__codelineno-133-3" name="__codelineno-133-3" href="#__codelineno-133-3"></a><span class="w"> </span><span class="nx">subject</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;Campaign Ready&#39;</span><span class="p">,</span>
</span><span id="__span-133-4"><a id="__codelineno-133-4" name="__codelineno-133-4" href="#__codelineno-133-4"></a><span class="w"> </span><span class="nx">template</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;campaign-email&#39;</span><span class="p">,</span>
</span><span id="__span-133-5"><a id="__codelineno-133-5" name="__codelineno-133-5" href="#__codelineno-133-5"></a><span class="w"> </span><span class="nx">variables</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-133-6"><a id="__codelineno-133-6" name="__codelineno-133-6" href="#__codelineno-133-6"></a><span class="w"> </span><span class="nx">firstName</span><span class="o">:</span><span class="w"> </span><span class="kt">user.name.split</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">)[</span><span class="mf">0</span><span class="p">],</span>
</span><span id="__span-133-7"><a id="__codelineno-133-7" name="__codelineno-133-7" href="#__codelineno-133-7"></a><span class="w"> </span><span class="nx">campaignName</span><span class="o">:</span><span class="w"> </span><span class="kt">campaign.name</span><span class="p">,</span>
</span><span id="__span-133-8"><a id="__codelineno-133-8" name="__codelineno-133-8" href="#__codelineno-133-8"></a><span class="w"> </span><span class="nx">campaignUrl</span><span class="o">:</span><span class="w"> </span><span class="sb">`</span><span class="si">${</span><span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">PUBLIC_URL</span><span class="si">}</span><span class="sb">/campaigns/</span><span class="si">${</span><span class="nx">campaign</span><span class="p">.</span><span class="nx">id</span><span class="si">}</span><span class="sb">`</span>
</span><span id="__span-133-9"><a id="__codelineno-133-9" name="__codelineno-133-9" href="#__codelineno-133-9"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-133-10"><a id="__codelineno-133-10" name="__codelineno-133-10" href="#__codelineno-133-10"></a><span class="p">});</span>
</span></code></pre></div>
<p><strong>Solution 3: Use default values</strong></p>
<div class="language-html highlight"><pre><span></span><code><span id="__span-134-1"><a id="__codelineno-134-1" name="__codelineno-134-1" href="#__codelineno-134-1"></a><span class="cm">&lt;!-- In template, provide fallback --&gt;</span>
</span><span id="__span-134-2"><a id="__codelineno-134-2" name="__codelineno-134-2" href="#__codelineno-134-2"></a><span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span>Hello {{firstName || &#39;Friend&#39;}}<span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
</span></code></pre></div>
<p><strong>Solution 4: Validate before sending</strong></p>
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-135-1"><a id="__codelineno-135-1" name="__codelineno-135-1" href="#__codelineno-135-1"></a><span class="c1">// Check all required variables exist</span>
</span><span id="__span-135-2"><a id="__codelineno-135-2" name="__codelineno-135-2" href="#__codelineno-135-2"></a><span class="kd">const</span><span class="w"> </span><span class="nx">required</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s1">&#39;firstName&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;campaignName&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;campaignUrl&#39;</span><span class="p">];</span>
</span><span id="__span-135-3"><a id="__codelineno-135-3" name="__codelineno-135-3" href="#__codelineno-135-3"></a><span class="kd">const</span><span class="w"> </span><span class="nx">missing</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">required</span><span class="p">.</span><span class="nx">filter</span><span class="p">(</span><span class="nx">key</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="o">!</span><span class="nx">variables</span><span class="p">[</span><span class="nx">key</span><span class="p">]);</span>
</span><span id="__span-135-4"><a id="__codelineno-135-4" name="__codelineno-135-4" href="#__codelineno-135-4"></a>
</span><span id="__span-135-5"><a id="__codelineno-135-5" name="__codelineno-135-5" href="#__codelineno-135-5"></a><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">missing</span><span class="p">.</span><span class="nx">length</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="mf">0</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-135-6"><a id="__codelineno-135-6" name="__codelineno-135-6" href="#__codelineno-135-6"></a><span class="w"> </span><span class="k">throw</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="ne">Error</span><span class="p">(</span><span class="sb">`Missing template variables: </span><span class="si">${</span><span class="nx">missing</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;, &#39;</span><span class="p">)</span><span class="si">}</span><span class="sb">`</span><span class="p">);</span>
</span><span id="__span-135-7"><a id="__codelineno-135-7" name="__codelineno-135-7" href="#__codelineno-135-7"></a><span class="p">}</span>
</span></code></pre></div>
<h4 id="prevention_22">Prevention<a class="headerlink" href="#prevention_22" title="Permanent link">&para;</a></h4>
<ul>
<li><strong>Template validation</strong> - Check variables on save</li>
<li><strong>TypeScript types</strong> - Type template variables</li>
<li><strong>Documentation</strong> - Document required variables</li>
<li><strong>Default values</strong> - Provide sensible defaults</li>
</ul>
<hr />
<h2 id="quick-reference-table">Quick Reference Table<a class="headerlink" href="#quick-reference-table" title="Permanent link">&para;</a></h2>
<table>
<thead>
<tr>
<th>Error Code/Message</th>
<th>Category</th>
<th>Common Cause</th>
<th>Quick Fix</th>
<th>Severity</th>
</tr>
</thead>
<tbody>
<tr>
<td>401 Unauthorized</td>
<td>Auth</td>
<td>Token expired</td>
<td>Re-login</td>
<td>🟠</td>
</tr>
<tr>
<td>403 Forbidden</td>
<td>Auth</td>
<td>Wrong role</td>
<td>Check user role</td>
<td>🟠</td>
</tr>
<tr>
<td>404 Not Found</td>
<td>API</td>
<td>Wrong URL/ID</td>
<td>Verify resource exists</td>
<td>🟢</td>
</tr>
<tr>
<td>422 Unprocessable</td>
<td>Validation</td>
<td>Constraint violation</td>
<td>Check validation details</td>
<td>🟡</td>
</tr>
<tr>
<td>500 Server Error</td>
<td>API</td>
<td>Code bug</td>
<td>Check API logs</td>
<td>🔴</td>
</tr>
<tr>
<td>ECONNREFUSED</td>
<td>Database</td>
<td>DB not running</td>
<td>Start database</td>
<td>🔴</td>
</tr>
<tr>
<td>Too many connections</td>
<td>Database</td>
<td>Connection leak</td>
<td>Restart API</td>
<td>🟠</td>
</tr>
<tr>
<td>Unique constraint</td>
<td>Database</td>
<td>Duplicate record</td>
<td>Use upsert or different value</td>
<td>🟡</td>
</tr>
<tr>
<td>Foreign key constraint</td>
<td>Database</td>
<td>Parent missing</td>
<td>Create parent first</td>
<td>🟡</td>
</tr>
<tr>
<td>Network Error</td>
<td>Frontend</td>
<td>API down</td>
<td>Check API status</td>
<td>🟠</td>
</tr>
<tr>
<td>CORS Error</td>
<td>Frontend</td>
<td>Origin not allowed</td>
<td>Add to CORS_ORIGINS</td>
<td>🟠</td>
</tr>
<tr>
<td>Module not found</td>
<td>Frontend</td>
<td>Missing package</td>
<td>npm install</td>
<td>🟡</td>
</tr>
<tr>
<td>File too large</td>
<td>Upload</td>
<td>Exceeds 10GB</td>
<td>Compress or increase limit</td>
<td>🟡</td>
</tr>
<tr>
<td>Invalid file type</td>
<td>Upload</td>
<td>Wrong format</td>
<td>Convert to MP4</td>
<td>🟢</td>
</tr>
<tr>
<td>Upload timeout</td>
<td>Upload</td>
<td>Slow network</td>
<td>Increase timeout</td>
<td>🟡</td>
</tr>
<tr>
<td>SMTP failed</td>
<td>Email</td>
<td>Wrong credentials</td>
<td>Check SMTP config</td>
<td>🔴</td>
</tr>
<tr>
<td>Template not found</td>
<td>Email</td>
<td>Missing file</td>
<td>Create template</td>
<td>🟠</td>
</tr>
<tr>
<td>Variable missing</td>
<td>Email</td>
<td>Not provided</td>
<td>Add to variables object</td>
<td>🟡</td>
</tr>
</tbody>
</table>
<hr />
<h2 id="when-to-report-bugs">When to Report Bugs<a class="headerlink" href="#when-to-report-bugs" title="Permanent link">&para;</a></h2>
<h3 id="report-these">Report These<a class="headerlink" href="#report-these" title="Permanent link">&para;</a></h3>
<p><strong>Unexpected behavior</strong> - System does something wrong</p>
<ul>
<li>500 errors (unless caused by your config)</li>
<li>Data corruption</li>
<li>Security vulnerabilities</li>
<li>Performance regressions</li>
</ul>
<p><strong>Missing features</strong> - Documented feature doesn't work</p>
<ul>
<li>API endpoint returns 404 but is documented</li>
<li>UI button does nothing</li>
<li>Feature flag doesn't enable feature</li>
</ul>
<p><strong>Unclear documentation</strong> - Can't figure out how to do something</p>
<ul>
<li>Documentation contradicts actual behavior</li>
<li>Missing setup steps</li>
<li>Confusing error messages</li>
</ul>
<h3 id="dont-report-these">Don't Report These<a class="headerlink" href="#dont-report-these" title="Permanent link">&para;</a></h3>
<p><strong>Configuration errors</strong> - Your setup is wrong</p>
<ul>
<li>Missing .env variables</li>
<li>Wrong database credentials</li>
<li>Port conflicts</li>
</ul>
<p><strong>Environment issues</strong> - Your system is incompatible</p>
<ul>
<li>Old Docker version</li>
<li>Missing dependencies</li>
<li>Network restrictions</li>
</ul>
<p><strong>User errors</strong> - Misunderstanding how to use</p>
<ul>
<li>Wrong API endpoint used</li>
<li>Invalid data format</li>
<li>Permission errors from lack of role</li>
</ul>
<h3 id="how-to-report">How to Report<a class="headerlink" href="#how-to-report" title="Permanent link">&para;</a></h3>
<ol>
<li><strong>Check this troubleshooting guide first</strong></li>
<li><strong>Search existing GitHub issues</strong></li>
<li><strong>If new, create issue with:</strong></li>
<li>Clear title describing problem</li>
<li>Steps to reproduce</li>
<li>Expected vs actual behavior</li>
<li>Relevant logs (sanitize sensitive data)</li>
<li>System information (Docker version, OS, etc.)</li>
</ol>
<hr />
<h2 id="related-documentation">Related Documentation<a class="headerlink" href="#related-documentation" title="Permanent link">&para;</a></h2>
<h3 id="general-documentation">General Documentation<a class="headerlink" href="#general-documentation" title="Permanent link">&para;</a></h3>
<ul>
<li><a href="../user/installation.md">Installation Guide</a> - Setup instructions</li>
<li><a href="../technical/architecture.md">Architecture Overview</a> - System design</li>
<li><a href="../technical/api-reference.md">API Reference</a> - API endpoints</li>
</ul>
<h3 id="specific-troubleshooting">Specific Troubleshooting<a class="headerlink" href="#specific-troubleshooting" title="Permanent link">&para;</a></h3>
<ul>
<li><a href="../docker-issues/">Docker Issues</a> - Container problems</li>
<li><a href="../database-issues/">Database Issues</a> - PostgreSQL errors</li>
<li><a href="../auth-issues/">Auth Issues</a> - Authentication problems</li>
<li><a href="../geocoding-issues/">Geocoding Issues</a> - Map and geocoding</li>
<li><a href="../email-issues/">Email Issues</a> - SMTP and templates</li>
<li><a href="../monitoring-issues/">Monitoring Issues</a> - Prometheus and Grafana</li>
</ul>
<h3 id="support">Support<a class="headerlink" href="#support" title="Permanent link">&para;</a></h3>
<ul>
<li><a href="../faq/">FAQ</a> - Frequently asked questions</li>
<li><a href="../performance-optimization/">Performance Optimization</a> - Speed improvements</li>
<li><a href="https://github.com/yourusername/changemaker.lite/issues">GitHub Issues</a> - Report bugs</li>
</ul>
<hr />
<p><strong>Last Updated:</strong> February 2026
<strong>Version:</strong> V2.0
<strong>Status:</strong> Complete</p>
</article>
</div>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg>
Back to top
</button>
</main>
<footer class="md-footer">
<nav class="md-footer__inner md-grid" aria-label="Footer" >
<a href="../faq/" class="md-footer__link md-footer__link--prev" aria-label="Previous: FAQ">
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</div>
<div class="md-footer__title">
<span class="md-footer__direction">
Previous
</span>
<div class="md-ellipsis">
FAQ
</div>
</div>
</a>
<a href="../auth-issues/" class="md-footer__link md-footer__link--next" aria-label="Next: Auth Issues">
<div class="md-footer__title">
<span class="md-footer__direction">
Next
</span>
<div class="md-ellipsis">
Auth Issues
</div>
</div>
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11z"/></svg>
</div>
</a>
</nav>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
<div class="md-copyright__highlight">
Copyright &copy; 2024 The Bunker Operations <a href="#__consent">Change cookie settings</a>
</div>
</div>
<div class="md-social">
<a href="https://gitea.bnkops.com/admin" target="_blank" rel="noopener" title="Gitea Repository" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg>
</a>
<a href="https://listmonk.bnkops.com/subscription/form" target="_blank" rel="noopener" title="Newsletter" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M536.4-26.3c9.8-3.5 20.6-1 28 6.3s9.8 18.2 6.3 28l-178 496.9c-5 13.9-18.1 23.1-32.8 23.1-14.2 0-27-8.6-32.3-21.7l-64.2-158c-4.5-11-2.5-23.6 5.2-32.6l94.5-112.4c5.1-6.1 4.7-15-.9-20.6s-14.6-6-20.6-.9l-112.4 94.3c-9.1 7.6-21.6 9.6-32.6 5.2L38.1 216.8c-13.1-5.3-21.7-18.1-21.7-32.3 0-14.7 9.2-27.8 23.1-32.8z"/></svg>
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"annotate": null, "base": "../../..", "features": ["announce.dismiss", "content.action.edit", "content.action.view", "content.code.annotate", "content.code.copy", "content.tooltips", "navigation.expand", "navigation.footer", "navigation.indexes", "navigation.path", "navigation.prune", "navigation.sections", "navigation.tabs", "navigation.tabs.sticky", "navigation.top", "navigation.tracking", "search.highlight", "search.share", "search.suggest", "toc.follow"], "search": "../../../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../../../assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="../../../javascripts/home.js"></script>
<script src="../../../javascripts/github-widget.js"></script>
<script src="../../../javascripts/gitea-widget.js"></script>
<script src="../../../assets/js/env-config.js"></script>
<script src="../../../assets/js/video-player.js"></script>
</body>
</html>