{"record":{"id":"16c785206cdac591","repo":"paperclipai/paperclip","slug":"method-path-failed-with-status-body-er","errorCode":null,"errorMessage":"${method} ${path} failed with ${status}: ${body.error}","messagePattern":"(.+?) (.+?) failed with (.+?): (.+?)","errorType":"http","errorClass":"PaperclipApiError","httpStatus":null,"severity":"error","filePath":"packages/mcp-server/src/client.ts","lineNumber":103,"sourceCode":"      Authorization: `Bearer ${this.config.apiKey}`,\n      Accept: \"application/json\",\n    };\n    if (options.body !== undefined) {\n      headers[\"Content-Type\"] = \"application/json\";\n    }\n    if ((options.includeRunId ?? isWriteMethod(method)) && this.config.runId) {\n      headers[\"X-Paperclip-Run-Id\"] = this.config.runId;\n    }\n\n    const response = await fetch(url, {\n      method,\n      headers,\n      body: options.body === undefined ? undefined : JSON.stringify(options.body),\n    });\n    const parsedBody = await parseResponseBody(response);\n\n    if (!response.ok) {\n      throw new PaperclipApiError({\n        status: response.status,\n        method: method.toUpperCase(),\n        path,\n        body: parsedBody,\n        message: buildErrorMessage(method.toUpperCase(), path, response.status, parsedBody),\n      });\n    }\n\n    return parsedBody as T;\n  }\n}\n","sourceCodeStart":85,"sourceCodeEnd":115,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/packages/mcp-server/src/client.ts#L85-L115","documentation":"PaperclipMcpClient.requestJson throws a PaperclipApiError whenever the upstream Paperclip /api response is not OK. buildErrorMessage appends ': <body.error>' when the parsed response body is an object containing a string 'error' field — i.e. the server returned a structured JSON error envelope. The thrown object also carries status, method, path, and the full parsed body for programmatic handling.","triggerScenarios":"Any Paperclip API call returns non-2xx with a JSON body shaped like {\"error\":\"...\"}. Common: 400 validation errors, 404 on a missing issue/approval ID, 409 conflict on a checked-out issue, 422 on bad input — all of which Paperclip formats with an error string.","commonSituations":"Operating on a stale issue ID; calling an approval endpoint on an already-resolved approval; passing a malformed body to a write endpoint; auth/permission mismatch returning 403 with an error message.","solutions":["Read body.error on the PaperclipApiError for the precise upstream reason and address that.","Verify the issueId/approvalId/companyId being passed actually exist and are in scope.","Re-fetch the resource (e.g. GET the issue) to confirm its current state before retrying."],"exampleFix":"// before\ntry { await client.requestJson('POST', '/issues/x/comments', {body:{body:''}}) }\ncatch (e) { /* generic */ }\n// after\ntry { await client.requestJson('POST', '/issues/x/comments', {body:{body: text}}) }\ncatch (e) {\n  if (e instanceof PaperclipApiError) console.error(e.status, e.body?.error);\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isPaperclipApiError(e: unknown): e is { status: number; method: string; path: string; body: unknown; message: string } {\n  return typeof e === 'object' && e !== null && 'status' in e && typeof (e as any).status === 'number' && 'path' in e;\n}","tryCatchPattern":"try { await client.requestJson('POST', path, { body }) }\ncatch (e) {\n  if (isPaperclipApiError(e)) {\n    if (e.status === 404) handleMissing(e.path);\n    else if (e.status === 409) handleConflict(e.body?.error);\n    else throw e;\n  } else throw e;\n}","preventionTips":["Always narrow on PaperclipApiError.status rather than parsing message strings.","For write methods, GET the resource first to confirm state and avoid 409/422.","Surface body.error to the operator for actionable diagnostics."],"tags":["api-client","paperclip-mcp","http-error","upstream"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}