{"title":"Errors & Error Handling","slug":"errors","category":"api","summary":"HTTP status code, รูปแบบ error response, และวิธีกู้คืนจาก error ทั่วไป","audience":["human","llm"],"tags":["api","errors","troubleshooting","http"],"difficulty":"beginner","updated":"2026-06-27","word_count":364,"read_minutes":2,"llm_context":"Error format: { statusCode, error, message, docs? }\nCommon errors: 401 (auth), 404 (wrong path), 429 (rate limit), 500 (server)\n401 → check Mind Key/JWT, see /docs/getting-started/authentication\n404 → wrong path, GET /endpoints for valid list, do NOT guess paths\n429 → rate limited (?key= is 60/min), use Bearer header instead\n500 → server error, retry with backoff, check /health\ndocs field in error response links to relevant documentation.\n","lang":"th","translated":true,"requested_lang":"th","content_markdown":"\n# Errors & Error Handling\n\nSynapse ใช้ HTTP status code มาตรฐานพร้อมรูปแบบ error response ที่สม่ำเสมอ เอกสารหน้านี้อธิบายวิธีตีความและกู้คืนจาก error\n\n## รูปแบบ Error Response\n\nerror ทั้งหมดส่งกลับเป็น JSON ด้วยโครงสร้างนี้:\n\n```json\n{\n  \"statusCode\": 401,\n  \"error\": \"Unauthorized\",\n  \"message\": \"Mind Key fehlt oder ungültig.\",\n  \"docs\": \"https://synapse.schaefer.zone/docs/getting-started/authentication\"\n}\n```\n\n| Field | คำอธิบาย |\n|-------|-------------|\n| `statusCode` | HTTP status code |\n| `error` | ชื่อ HTTP status |\n| `message` | คำอธิบาย error ที่มนุษย์อ่านได้ |\n| `docs` | URL ไปยังเอกสารที่เกี่ยวข้อง (เมื่อเกี่ยวข้อง) |\n\n## HTTP Status Codes\n\n### 200 OK\n\nสำเร็จ request ถูกประมวลผลถูกต้อง\n\n### 201 Created\n\nสำเร็จ สร้าง resource ใหม่ (เช่น `POST /memory`)\n\n### 204 No Content\n\nสำเร็จ ไม่มี body ส่งกลับ (เช่น `DELETE /memory/:id`)\n\n### 400 Bad Request\n\nrequest ผิดรูปแบบ สาเหตุทั่วไป:\n\n- ขาด JSON field ที่จำเป็น\n- ไวยากรณ์ JSON ไม่ถูกต้อง\n- ค่า enum ไม่ถูกต้อง (เช่น category ผิด)\n\n```json\n{\n  \"statusCode\": 400,\n  \"error\": \"Bad Request\",\n  \"message\": \"category must be one of: identity, preference, fact, project, skill, mistake, context, note, credentials\"\n}\n```\n\n**วิธีแก้:** ตรวจสอบ request body กับ API docs ตรวจสอบว่า field ที่จำเป็นทั้งหมดมีและมีค่าที่ถูกต้อง\n\n### 401 Unauthorized\n\nการยืนยันตัวตนล้มเหลว สาเหตุทั่วไป:\n\n- ขาด `Authorization` header\n- Mind Key หรือ JWT ไม่ถูกต้อง\n- ใช้ Mind Key ในที่ที่ต้องใช้ JWT (หรือกลับกัน)\n\n```json\n{\n  \"statusCode\": 401,\n  \"error\": \"Unauthorized\",\n  \"message\": \"Mind Key fehlt oder ungültig.\",\n  \"docs\": \"https://synapse.schaefer.zone/docs/getting-started/authentication\"\n}\n```\n\n**วิธีแก้:** ตรวจสอบ token ของคุณ ดู [Authentication](/docs/getting-started/authentication)\n\n### 403 Forbidden\n\nคุณยืนยันตัวตนแล้วแต่ไม่ได้รับอนุญาตให้ทำ action นี้ สาเหตุทั่วไป:\n\n- พยายามลบ mind ของผู้ใช้อื่น\n- พยายาม verify memory ด้วย Mind Key (ต้องใช้ JWT)\n- Mind ถูกปิดใช้งาน\n\n**วิธีแก้:** ตรวจสอบว่าคุณใช้ประเภท token ที่ถูกต้องสำหรับ endpoint นี้\n\n### 404 Not Found\n\npath หรือ resource ที่ร้องขอไม่มีอยู่\n\n> [!CRITICAL]\n> **อย่าเดา path ของ endpoint** มีเพียง path ที่แสดงใน `GET /endpoints` เท่านั้นที่มีอยู่ หากคุณได้ 404 แสดงว่าคุณใช้ path ผิด\n\n```json\n{\n  \"statusCode\": 404,\n  \"error\": \"Not Found\",\n  \"message\": \"Route GET /memory/list not found\",\n  \"docs\": \"https://synapse.schaefer.zone/docs/api/errors\"\n}\n```\n\n**วิธีแก้:** เรียก `GET /endpoints` เพื่อดูรายการ endpoint ที่ถูกต้อง เปรียบเทียบ URL ของคุณกับรายการทีละตัวอักษร\n\n### 409 Conflict\n\nrequest ขัดแย้งกับสถานะที่มีอยู่ สาเหตุทั่วไป:\n\n- พยายามลงทะเบียนด้วย email ที่มีอยู่แล้ว\n- ซ้ำ webhook URL\n\n**วิธีแก้:** ใช้ค่าอื่น หรือใช้ `PUT` เพื่ออัปเดต resource ที่มีอยู่\n\n### 429 Too Many Requests\n\nคุณกระทบ rate limit ใช้เฉพาะกับ auth ผ่าน `?key=` query parameter (60/นาที)\n\n```json\n{\n  \"statusCode\": 429,\n  \"error\": \"Too Many Requests\",\n  \"message\": \"Rate limit exceeded. Use Authorization header for unlimited access.\"\n}\n```\n\nResponse headers:\n\n```\nX-RateLimit-Limit: 60\nX-RateLimit-Remaining: 0\nRetry-After: 42\n```\n\n**วิธีแก้:** เปลี่ยนไปใช้ `Authorization: Bearer` header (ไม่จำกัดอัตรา) หรือรอ `Retry-After` วินาที\n\n### 500 Internal Server Error\n\nserver error ไม่ควรเกิดขึ้น — หากเกิด ถือเป็น bug\n\n**วิธีแก้:**\n\n1. Retry ด้วย exponential backoff (1s, 2s, 4s, 8s)\n2. ตรวจสอบ `GET /health` เพื่อดูว่า server ยังทำงานอยู่หรือไม่\n3. หากยังเกิดขึ้นเรื่อย ๆ ให้รายงาน error\n\n### 503 Service Unavailable\n\nserver ล่มชั่วคราว (เช่น ระหว่าง deploy, database migration)\n\n**วิธีแก้:** รอแล้ว retry ตรวจสอบ `GET /health`\n\n## รูปแบบการกู้คืน\n\n### Retry ด้วย exponential backoff\n\n```python\nimport time\nimport requests\n\ndef call_with_retry(url, max_retries=3):\n    for attempt in range(max_retries):\n        try:\n            r = requests.get(url, headers={\"Authorization\": f\"Bearer {KEY}\"})\n            if r.status_code == 429:\n                wait = int(r.headers.get(\"Retry-After\", 60))\n                time.sleep(wait)\n                continue\n            if r.status_code >= 500:\n                time.sleep(2 ** attempt)\n                continue\n            return r\n        except requests.RequestException:\n            time.sleep(2 ** attempt)\n    raise Exception(f\"Failed after {max_retries} retries\")\n```\n\n### การจัดการ auth error\n\n```python\ndef safe_call(url, key):\n    r = requests.get(url, headers={\"Authorization\": f\"Bearer {key}\"})\n    if r.status_code == 401:\n        # Mind Key invalid — alert user\n        raise AuthError(\"Mind Key invalid or expired\")\n    return r\n```\n\n## สถานการณ์ error ทั่วไป\n\n### \"Mind Key fehlt oder ungültig\"\n\n- คุณลืม `Authorization` header\n- คุณใช้ `?key=` แต่ key ผิด\n- คุณใช้ JWT ในที่ที่ต้องใช้ Mind Key\n\n### \"Route not found\"\n\n- คุณเดา path ที่ไม่มีอยู่\n- คุณใช้ verb ผิด (เช่น `GET /memory` เทียบกับ `POST /memory`)\n- ตรวจสอบ `GET /endpoints` สำหรับ path ที่ถูกต้อง\n\n### \"Rate limit exceeded\"\n\n- คุณใช้ `?key=` และเกิน 60 req/min\n- เปลี่ยนไปใช้ `Authorization: Bearer` header\n\n## ขั้นตอนถัดไป\n\n- [Authentication](/docs/getting-started/authentication)\n- [API Overview](/docs/api/overview)\n- [Rate Limits](/docs/api/rate-limits)\n","content_html":"<h1>Errors &amp; Error Handling</h1>\n<p>Synapse ใช้ HTTP status code มาตรฐานพร้อมรูปแบบ error response ที่สม่ำเสมอ เอกสารหน้านี้อธิบายวิธีตีความและกู้คืนจาก error</p>\n<h2>รูปแบบ Error Response</h2>\n<p>error ทั้งหมดส่งกลับเป็น JSON ด้วยโครงสร้างนี้:</p>\n<pre><code class=\"hljs language-json\"><span class=\"hljs-punctuation\">{</span>\n  <span class=\"hljs-attr\">&quot;statusCode&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-number\">401</span><span class=\"hljs-punctuation\">,</span>\n  <span class=\"hljs-attr\">&quot;error&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-string\">&quot;Unauthorized&quot;</span><span class=\"hljs-punctuation\">,</span>\n  <span class=\"hljs-attr\">&quot;message&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-string\">&quot;Mind Key fehlt oder ungültig.&quot;</span><span class=\"hljs-punctuation\">,</span>\n  <span class=\"hljs-attr\">&quot;docs&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-string\">&quot;https://synapse.schaefer.zone/docs/getting-started/authentication&quot;</span>\n<span class=\"hljs-punctuation\">}</span></code></pre><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>คำอธิบาย</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>statusCode</code></td>\n<td>HTTP status code</td>\n</tr>\n<tr>\n<td><code>error</code></td>\n<td>ชื่อ HTTP status</td>\n</tr>\n<tr>\n<td><code>message</code></td>\n<td>คำอธิบาย error ที่มนุษย์อ่านได้</td>\n</tr>\n<tr>\n<td><code>docs</code></td>\n<td>URL ไปยังเอกสารที่เกี่ยวข้อง (เมื่อเกี่ยวข้อง)</td>\n</tr>\n</tbody></table>\n<h2>HTTP Status Codes</h2>\n<h3>200 OK</h3>\n<p>สำเร็จ request ถูกประมวลผลถูกต้อง</p>\n<h3>201 Created</h3>\n<p>สำเร็จ สร้าง resource ใหม่ (เช่น <code>POST /memory</code>)</p>\n<h3>204 No Content</h3>\n<p>สำเร็จ ไม่มี body ส่งกลับ (เช่น <code>DELETE /memory/:id</code>)</p>\n<h3>400 Bad Request</h3>\n<p>request ผิดรูปแบบ สาเหตุทั่วไป:</p>\n<ul>\n<li>ขาด JSON field ที่จำเป็น</li>\n<li>ไวยากรณ์ JSON ไม่ถูกต้อง</li>\n<li>ค่า enum ไม่ถูกต้อง (เช่น category ผิด)</li>\n</ul>\n<pre><code class=\"hljs language-json\"><span class=\"hljs-punctuation\">{</span>\n  <span class=\"hljs-attr\">&quot;statusCode&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-number\">400</span><span class=\"hljs-punctuation\">,</span>\n  <span class=\"hljs-attr\">&quot;error&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-string\">&quot;Bad Request&quot;</span><span class=\"hljs-punctuation\">,</span>\n  <span class=\"hljs-attr\">&quot;message&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-string\">&quot;category must be one of: identity, preference, fact, project, skill, mistake, context, note, credentials&quot;</span>\n<span class=\"hljs-punctuation\">}</span></code></pre><p><strong>วิธีแก้:</strong> ตรวจสอบ request body กับ API docs ตรวจสอบว่า field ที่จำเป็นทั้งหมดมีและมีค่าที่ถูกต้อง</p>\n<h3>401 Unauthorized</h3>\n<p>การยืนยันตัวตนล้มเหลว สาเหตุทั่วไป:</p>\n<ul>\n<li>ขาด <code>Authorization</code> header</li>\n<li>Mind Key หรือ JWT ไม่ถูกต้อง</li>\n<li>ใช้ Mind Key ในที่ที่ต้องใช้ JWT (หรือกลับกัน)</li>\n</ul>\n<pre><code class=\"hljs language-json\"><span class=\"hljs-punctuation\">{</span>\n  <span class=\"hljs-attr\">&quot;statusCode&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-number\">401</span><span class=\"hljs-punctuation\">,</span>\n  <span class=\"hljs-attr\">&quot;error&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-string\">&quot;Unauthorized&quot;</span><span class=\"hljs-punctuation\">,</span>\n  <span class=\"hljs-attr\">&quot;message&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-string\">&quot;Mind Key fehlt oder ungültig.&quot;</span><span class=\"hljs-punctuation\">,</span>\n  <span class=\"hljs-attr\">&quot;docs&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-string\">&quot;https://synapse.schaefer.zone/docs/getting-started/authentication&quot;</span>\n<span class=\"hljs-punctuation\">}</span></code></pre><p><strong>วิธีแก้:</strong> ตรวจสอบ token ของคุณ ดู <a href=\"/docs/getting-started/authentication\">Authentication</a></p>\n<h3>403 Forbidden</h3>\n<p>คุณยืนยันตัวตนแล้วแต่ไม่ได้รับอนุญาตให้ทำ action นี้ สาเหตุทั่วไป:</p>\n<ul>\n<li>พยายามลบ mind ของผู้ใช้อื่น</li>\n<li>พยายาม verify memory ด้วย Mind Key (ต้องใช้ JWT)</li>\n<li>Mind ถูกปิดใช้งาน</li>\n</ul>\n<p><strong>วิธีแก้:</strong> ตรวจสอบว่าคุณใช้ประเภท token ที่ถูกต้องสำหรับ endpoint นี้</p>\n<h3>404 Not Found</h3>\n<p>path หรือ resource ที่ร้องขอไม่มีอยู่</p>\n<div class=\"callout callout-critical\">**อย่าเดา path ของ endpoint** มีเพียง path ที่แสดงใน `GET /endpoints` เท่านั้นที่มีอยู่ หากคุณได้ 404 แสดงว่าคุณใช้ path ผิด</div><pre><code class=\"hljs language-json\"><span class=\"hljs-punctuation\">{</span>\n  <span class=\"hljs-attr\">&quot;statusCode&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-number\">404</span><span class=\"hljs-punctuation\">,</span>\n  <span class=\"hljs-attr\">&quot;error&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-string\">&quot;Not Found&quot;</span><span class=\"hljs-punctuation\">,</span>\n  <span class=\"hljs-attr\">&quot;message&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-string\">&quot;Route GET /memory/list not found&quot;</span><span class=\"hljs-punctuation\">,</span>\n  <span class=\"hljs-attr\">&quot;docs&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-string\">&quot;https://synapse.schaefer.zone/docs/api/errors&quot;</span>\n<span class=\"hljs-punctuation\">}</span></code></pre><p><strong>วิธีแก้:</strong> เรียก <code>GET /endpoints</code> เพื่อดูรายการ endpoint ที่ถูกต้อง เปรียบเทียบ URL ของคุณกับรายการทีละตัวอักษร</p>\n<h3>409 Conflict</h3>\n<p>request ขัดแย้งกับสถานะที่มีอยู่ สาเหตุทั่วไป:</p>\n<ul>\n<li>พยายามลงทะเบียนด้วย email ที่มีอยู่แล้ว</li>\n<li>ซ้ำ webhook URL</li>\n</ul>\n<p><strong>วิธีแก้:</strong> ใช้ค่าอื่น หรือใช้ <code>PUT</code> เพื่ออัปเดต resource ที่มีอยู่</p>\n<h3>429 Too Many Requests</h3>\n<p>คุณกระทบ rate limit ใช้เฉพาะกับ auth ผ่าน <code>?key=</code> query parameter (60/นาที)</p>\n<pre><code class=\"hljs language-json\"><span class=\"hljs-punctuation\">{</span>\n  <span class=\"hljs-attr\">&quot;statusCode&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-number\">429</span><span class=\"hljs-punctuation\">,</span>\n  <span class=\"hljs-attr\">&quot;error&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-string\">&quot;Too Many Requests&quot;</span><span class=\"hljs-punctuation\">,</span>\n  <span class=\"hljs-attr\">&quot;message&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-string\">&quot;Rate limit exceeded. Use Authorization header for unlimited access.&quot;</span>\n<span class=\"hljs-punctuation\">}</span></code></pre><p>Response headers:</p>\n<pre><code class=\"hljs language-plaintext\">X-RateLimit-Limit: 60\nX-RateLimit-Remaining: 0\nRetry-After: 42</code></pre><p><strong>วิธีแก้:</strong> เปลี่ยนไปใช้ <code>Authorization: Bearer</code> header (ไม่จำกัดอัตรา) หรือรอ <code>Retry-After</code> วินาที</p>\n<h3>500 Internal Server Error</h3>\n<p>server error ไม่ควรเกิดขึ้น — หากเกิด ถือเป็น bug</p>\n<p><strong>วิธีแก้:</strong></p>\n<ol>\n<li>Retry ด้วย exponential backoff (1s, 2s, 4s, 8s)</li>\n<li>ตรวจสอบ <code>GET /health</code> เพื่อดูว่า server ยังทำงานอยู่หรือไม่</li>\n<li>หากยังเกิดขึ้นเรื่อย ๆ ให้รายงาน error</li>\n</ol>\n<h3>503 Service Unavailable</h3>\n<p>server ล่มชั่วคราว (เช่น ระหว่าง deploy, database migration)</p>\n<p><strong>วิธีแก้:</strong> รอแล้ว retry ตรวจสอบ <code>GET /health</code></p>\n<h2>รูปแบบการกู้คืน</h2>\n<h3>Retry ด้วย exponential backoff</h3>\n<pre><code class=\"hljs language-python\"><span class=\"hljs-keyword\">import</span> time\n<span class=\"hljs-keyword\">import</span> requests\n\n<span class=\"hljs-keyword\">def</span> <span class=\"hljs-title function_\">call_with_retry</span>(<span class=\"hljs-params\">url, max_retries=<span class=\"hljs-number\">3</span></span>):\n    <span class=\"hljs-keyword\">for</span> attempt <span class=\"hljs-keyword\">in</span> <span class=\"hljs-built_in\">range</span>(max_retries):\n        <span class=\"hljs-keyword\">try</span>:\n            r = requests.get(url, headers={<span class=\"hljs-string\">&quot;Authorization&quot;</span>: <span class=\"hljs-string\">f&quot;Bearer <span class=\"hljs-subst\">{KEY}</span>&quot;</span>})\n            <span class=\"hljs-keyword\">if</span> r.status_code == <span class=\"hljs-number\">429</span>:\n                wait = <span class=\"hljs-built_in\">int</span>(r.headers.get(<span class=\"hljs-string\">&quot;Retry-After&quot;</span>, <span class=\"hljs-number\">60</span>))\n                time.sleep(wait)\n                <span class=\"hljs-keyword\">continue</span>\n            <span class=\"hljs-keyword\">if</span> r.status_code &gt;= <span class=\"hljs-number\">500</span>:\n                time.sleep(<span class=\"hljs-number\">2</span> ** attempt)\n                <span class=\"hljs-keyword\">continue</span>\n            <span class=\"hljs-keyword\">return</span> r\n        <span class=\"hljs-keyword\">except</span> requests.RequestException:\n            time.sleep(<span class=\"hljs-number\">2</span> ** attempt)\n    <span class=\"hljs-keyword\">raise</span> Exception(<span class=\"hljs-string\">f&quot;Failed after <span class=\"hljs-subst\">{max_retries}</span> retries&quot;</span>)</code></pre><h3>การจัดการ auth error</h3>\n<pre><code class=\"hljs language-python\"><span class=\"hljs-keyword\">def</span> <span class=\"hljs-title function_\">safe_call</span>(<span class=\"hljs-params\">url, key</span>):\n    r = requests.get(url, headers={<span class=\"hljs-string\">&quot;Authorization&quot;</span>: <span class=\"hljs-string\">f&quot;Bearer <span class=\"hljs-subst\">{key}</span>&quot;</span>})\n    <span class=\"hljs-keyword\">if</span> r.status_code == <span class=\"hljs-number\">401</span>:\n        <span class=\"hljs-comment\"># Mind Key invalid — alert user</span>\n        <span class=\"hljs-keyword\">raise</span> AuthError(<span class=\"hljs-string\">&quot;Mind Key invalid or expired&quot;</span>)\n    <span class=\"hljs-keyword\">return</span> r</code></pre><h2>สถานการณ์ error ทั่วไป</h2>\n<h3>&quot;Mind Key fehlt oder ungültig&quot;</h3>\n<ul>\n<li>คุณลืม <code>Authorization</code> header</li>\n<li>คุณใช้ <code>?key=</code> แต่ key ผิด</li>\n<li>คุณใช้ JWT ในที่ที่ต้องใช้ Mind Key</li>\n</ul>\n<h3>&quot;Route not found&quot;</h3>\n<ul>\n<li>คุณเดา path ที่ไม่มีอยู่</li>\n<li>คุณใช้ verb ผิด (เช่น <code>GET /memory</code> เทียบกับ <code>POST /memory</code>)</li>\n<li>ตรวจสอบ <code>GET /endpoints</code> สำหรับ path ที่ถูกต้อง</li>\n</ul>\n<h3>&quot;Rate limit exceeded&quot;</h3>\n<ul>\n<li>คุณใช้ <code>?key=</code> และเกิน 60 req/min</li>\n<li>เปลี่ยนไปใช้ <code>Authorization: Bearer</code> header</li>\n</ul>\n<h2>ขั้นตอนถัดไป</h2>\n<ul>\n<li><a href=\"/docs/getting-started/authentication\">Authentication</a></li>\n<li><a href=\"/docs/api/overview\">API Overview</a></li>\n<li><a href=\"/docs/api/rate-limits\">Rate Limits</a></li>\n</ul>\n","urls":{"html":"/docs/api/errors","text":"/docs/api/errors?format=text","json":"/docs/api/errors?format=json","llm":"/docs/api/errors?format=llm"},"translations_available":["en","zh","hi","es","fr","ar","pt","ru","ja","de","it","ko","nl","pl","tr","sv","vi","th","id","uk"]}