{"title":"오류 및 오류 처리","slug":"errors","category":"api","summary":"HTTP 상태 코드, 오류 응답 형식, 그리고 일반적인 오류로부터 복구하는 방법.","audience":["human","llm"],"tags":["api","errors","troubleshooting","http"],"difficulty":"beginner","updated":"2026-06-27","word_count":427,"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":"ko","translated":true,"requested_lang":"ko","content_markdown":"\n# 오류 및 오류 처리\n\nSynapse는 표준 HTTP 상태 코드와 일관된 오류 응답 형식을 사용합니다.\n이 페이지에서는 오류를 해석하고 복구하는 방법을 설명합니다.\n\n## 오류 응답 형식\n\n모든 오류는 다음 구조의 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| 필드 | 설명 |\n|-------|-------------|\n| `statusCode` | HTTP 상태 코드 |\n| `error` | HTTP 상태 이름 |\n| `message` | 사람이 읽을 수 있는 오류 설명 |\n| `docs` | 관련 문서 URL (해당되는 경우) |\n\n## HTTP 상태 코드\n\n### 200 OK\n\n성공입니다. 요청이 올바르게 처리되었습니다.\n\n### 201 Created\n\n성공입니다. 새 리소스가 생성되었습니다 (예: `POST /memory`).\n\n### 204 No Content\n\n성공입니다. 본문이 반환되지 않았습니다 (예: `DELETE /memory/:id`).\n\n### 400 Bad Request\n\n요청이 잘못되었습니다. 일반적인 원인:\n\n- 필수 JSON 필드 누락\n- 잘못된 JSON 구문\n- 잘못된 enum 값 (예: 잘못된 카테고리)\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**해결:** API 문서와 대조하여 요청 본문을 확인하십시오. 모든 필수 필드가\n존재하고 유효한 값을 가지고 있는지 확인하십시오.\n\n### 401 Unauthorized\n\n인증에 실패했습니다. 일반적인 원인:\n\n- `Authorization` 헤더 누락\n- 잘못된 Mind Key 또는 JWT\n- JWT가 필요한 곳에 Mind Key 사용 (또는 그 반대)\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**해결:** 토큰을 확인하십시오. [Authentication](/docs/getting-started/authentication)을 참조하십시오.\n\n### 403 Forbidden\n\n인증은 되었지만 이 작업을 수행할 권한이 없습니다. 일반적인 원인:\n\n- 다른 사용자의 마인드 삭제 시도\n- Mind Key로 memory 검증 시도 (JWT 필요)\n- 마인드가 비활성화됨\n\n**해결:** 이 엔드포인트에 올바른 토큰 유형을 사용하고 있는지 확인하십시오.\n\n### 404 Not Found\n\n요청한 경로 또는 리소스가 존재하지 않습니다.\n\n> [!CRITICAL]\n> **엔드포인트 경로를 추측하지 마십시오.** `GET /endpoints`에 나열된\n> 경로만 존재합니다. 404를 받았다면 잘못된 경로를 사용한 것입니다.\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`를 호출하여 유효한 엔드포인트 목록을\n확인하십시오. URL을 목록과 글자 단위로 비교하십시오.\n\n### 409 Conflict\n\n요청이 기존 상태와 충돌합니다. 일반적인 원인:\n\n- 이미 존재하는 이메일로 등록 시도\n- 중복된 webhook URL\n\n**해결:** 다른 값을 사용하거나, `PUT`을 사용하여 기존 리소스를\n업데이트하십시오.\n\n### 429 Too Many Requests\n\n속도 제한에 도달했습니다. `?key=` 쿼리 파라미터 인증에만 적용됩니다 (분당 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\n응답 헤더:\n\n```\nX-RateLimit-Limit: 60\nX-RateLimit-Remaining: 0\nRetry-After: 42\n```\n\n**해결:** `Authorization: Bearer` 헤더로 전환하거나 (속도 제한 없음),\n`Retry-After`초 동안 기다리십시오.\n\n### 500 Internal Server Error\n\n서버 오류입니다. 이런 일이 발생해서는 안 되며 — 발생한다면 버그입니다.\n\n**해결:**\n\n1. 지수 백오프로 재시도 (1초, 2초, 4초, 8초)\n2. `GET /health`를 확인하여 서버가 실행 중인지 확인\n3. 지속되면 오류를 보고하십시오\n\n### 503 Service Unavailable\n\n서버가 일시적으로 중단되었습니다 (예: 배포 중, 데이터베이스 마이그레이션).\n\n**해결:** 기다렸다가 재시도하십시오. `GET /health`를 확인하십시오.\n\n## 복구 패턴\n\n### 지수 백오프 재시도\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### 인증 오류 처리\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## 일반적인 오류 시나리오\n\n### \"Mind Key fehlt oder ungültig\"\n\n- `Authorization` 헤더를 잊음\n- `?key=`를 사용했지만 키가 잘못됨\n- Mind Key가 필요한 곳에 JWT를 사용 중\n\n### \"Route not found\"\n\n- 존재하지 않는 경로를 추측함\n- 동사를 잘못 사용함 (예: `GET /memory` vs `POST /memory`)\n- `GET /endpoints`에서 유효한 경로 확인\n\n### \"Rate limit exceeded\"\n\n- `?key=`를 사용하여 분당 60회 초과\n- `Authorization: Bearer` 헤더로 전환\n\n## 다음 단계\n\n- [Authentication](/docs/getting-started/authentication)\n- [API 개요](/docs/api/overview)\n- [속도 제한](/docs/api/rate-limits)\n","content_html":"<h1>오류 및 오류 처리</h1>\n<p>Synapse는 표준 HTTP 상태 코드와 일관된 오류 응답 형식을 사용합니다.\n이 페이지에서는 오류를 해석하고 복구하는 방법을 설명합니다.</p>\n<h2>오류 응답 형식</h2>\n<p>모든 오류는 다음 구조의 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>필드</th>\n<th>설명</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>statusCode</code></td>\n<td>HTTP 상태 코드</td>\n</tr>\n<tr>\n<td><code>error</code></td>\n<td>HTTP 상태 이름</td>\n</tr>\n<tr>\n<td><code>message</code></td>\n<td>사람이 읽을 수 있는 오류 설명</td>\n</tr>\n<tr>\n<td><code>docs</code></td>\n<td>관련 문서 URL (해당되는 경우)</td>\n</tr>\n</tbody></table>\n<h2>HTTP 상태 코드</h2>\n<h3>200 OK</h3>\n<p>성공입니다. 요청이 올바르게 처리되었습니다.</p>\n<h3>201 Created</h3>\n<p>성공입니다. 새 리소스가 생성되었습니다 (예: <code>POST /memory</code>).</p>\n<h3>204 No Content</h3>\n<p>성공입니다. 본문이 반환되지 않았습니다 (예: <code>DELETE /memory/:id</code>).</p>\n<h3>400 Bad Request</h3>\n<p>요청이 잘못되었습니다. 일반적인 원인:</p>\n<ul>\n<li>필수 JSON 필드 누락</li>\n<li>잘못된 JSON 구문</li>\n<li>잘못된 enum 값 (예: 잘못된 카테고리)</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> API 문서와 대조하여 요청 본문을 확인하십시오. 모든 필수 필드가\n존재하고 유효한 값을 가지고 있는지 확인하십시오.</p>\n<h3>401 Unauthorized</h3>\n<p>인증에 실패했습니다. 일반적인 원인:</p>\n<ul>\n<li><code>Authorization</code> 헤더 누락</li>\n<li>잘못된 Mind Key 또는 JWT</li>\n<li>JWT가 필요한 곳에 Mind Key 사용 (또는 그 반대)</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> 토큰을 확인하십시오. <a href=\"/docs/getting-started/authentication\">Authentication</a>을 참조하십시오.</p>\n<h3>403 Forbidden</h3>\n<p>인증은 되었지만 이 작업을 수행할 권한이 없습니다. 일반적인 원인:</p>\n<ul>\n<li>다른 사용자의 마인드 삭제 시도</li>\n<li>Mind Key로 memory 검증 시도 (JWT 필요)</li>\n<li>마인드가 비활성화됨</li>\n</ul>\n<p><strong>해결:</strong> 이 엔드포인트에 올바른 토큰 유형을 사용하고 있는지 확인하십시오.</p>\n<h3>404 Not Found</h3>\n<p>요청한 경로 또는 리소스가 존재하지 않습니다.</p>\n<div class=\"callout callout-critical\">**엔드포인트 경로를 추측하지 마십시오.** `GET /endpoints`에 나열된\n경로만 존재합니다. 404를 받았다면 잘못된 경로를 사용한 것입니다.</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>를 호출하여 유효한 엔드포인트 목록을\n확인하십시오. URL을 목록과 글자 단위로 비교하십시오.</p>\n<h3>409 Conflict</h3>\n<p>요청이 기존 상태와 충돌합니다. 일반적인 원인:</p>\n<ul>\n<li>이미 존재하는 이메일로 등록 시도</li>\n<li>중복된 webhook URL</li>\n</ul>\n<p><strong>해결:</strong> 다른 값을 사용하거나, <code>PUT</code>을 사용하여 기존 리소스를\n업데이트하십시오.</p>\n<h3>429 Too Many Requests</h3>\n<p>속도 제한에 도달했습니다. <code>?key=</code> 쿼리 파라미터 인증에만 적용됩니다 (분당 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>응답 헤더:</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> 헤더로 전환하거나 (속도 제한 없음),\n<code>Retry-After</code>초 동안 기다리십시오.</p>\n<h3>500 Internal Server Error</h3>\n<p>서버 오류입니다. 이런 일이 발생해서는 안 되며 — 발생한다면 버그입니다.</p>\n<p><strong>해결:</strong></p>\n<ol>\n<li>지수 백오프로 재시도 (1초, 2초, 4초, 8초)</li>\n<li><code>GET /health</code>를 확인하여 서버가 실행 중인지 확인</li>\n<li>지속되면 오류를 보고하십시오</li>\n</ol>\n<h3>503 Service Unavailable</h3>\n<p>서버가 일시적으로 중단되었습니다 (예: 배포 중, 데이터베이스 마이그레이션).</p>\n<p><strong>해결:</strong> 기다렸다가 재시도하십시오. <code>GET /health</code>를 확인하십시오.</p>\n<h2>복구 패턴</h2>\n<h3>지수 백오프 재시도</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>인증 오류 처리</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>일반적인 오류 시나리오</h2>\n<h3>&quot;Mind Key fehlt oder ungültig&quot;</h3>\n<ul>\n<li><code>Authorization</code> 헤더를 잊음</li>\n<li><code>?key=</code>를 사용했지만 키가 잘못됨</li>\n<li>Mind Key가 필요한 곳에 JWT를 사용 중</li>\n</ul>\n<h3>&quot;Route not found&quot;</h3>\n<ul>\n<li>존재하지 않는 경로를 추측함</li>\n<li>동사를 잘못 사용함 (예: <code>GET /memory</code> vs <code>POST /memory</code>)</li>\n<li><code>GET /endpoints</code>에서 유효한 경로 확인</li>\n</ul>\n<h3>&quot;Rate limit exceeded&quot;</h3>\n<ul>\n<li><code>?key=</code>를 사용하여 분당 60회 초과</li>\n<li><code>Authorization: Bearer</code> 헤더로 전환</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 개요</a></li>\n<li><a href=\"/docs/api/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"]}