{"record":{"id":"cbd5d6d05545e6a6","repo":"tinyhumansai/openhuman","slug":"method-body-error-message-json-stringify","errorCode":null,"errorMessage":"${method}: ${body.error.message || JSON.stringify(body.error)}","messagePattern":"\\$\\{method\\}: \\$\\{body\\.error\\.message \\|\\| JSON\\.stringify\\(body\\.error\\)\\}","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/test-memory-email-ingest.mjs","lineNumber":56,"sourceCode":"const RPC_URL = process.env.RPC_URL || \"http://127.0.0.1:7810/rpc\";\nconst OWNER = process.env.OWNER || \"stevent95@gmail.com\";\nconst PROVIDER = process.env.PROVIDER || \"gmail\";\nconst FIXTURE =\n  process.argv[2] ||\n  resolve(\"tests/fixtures/memory/composio_gmail_inbox.json\");\n\nlet rpcId = 0;\nasync function rpc(method, params) {\n  rpcId += 1;\n  const res = await fetch(RPC_URL, {\n    method: \"POST\",\n    headers: { \"content-type\": \"application/json\" },\n    body: JSON.stringify({ jsonrpc: \"2.0\", id: rpcId, method, params }),\n  });\n  if (!res.ok) throw new Error(`${method}: HTTP ${res.status} ${await res.text()}`);\n  const body = await res.json();\n  if (body.error) {\n    throw new Error(`${method}: ${body.error.message || JSON.stringify(body.error)}`);\n  }\n  return body.result;\n}\n\nfunction parseEmailDate(raw) {\n  if (!raw) return Date.now();\n  if (typeof raw === \"number\") return raw < 1e12 ? raw * 1000 : raw;\n  const ms = Date.parse(raw);\n  return Number.isFinite(ms) ? ms : Date.now();\n}\n\nfunction splitAddresses(value) {\n  if (!value) return [];\n  if (Array.isArray(value)) return value.filter(Boolean);\n  return String(value)\n    .split(/[;,]/)\n    .map((s) => s.trim())\n    .filter(Boolean);","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/scripts/test-memory-email-ingest.mjs#L38-L74","documentation":"The HTTP layer was fine (2xx) but the JSON-RPC envelope contains an `error` object — the core executed the dispatch and returned a JSON-RPC failure; the script surfaces body.error.message (or the stringified error). This is the core's own domain error, not a transport problem.","triggerScenarios":"Calling an unregistered method (typo, renamed namespace, or a feature-gated domain compiled out so its controllers answer unknown-method); params that fail validation (e.g. a fixture whose shape does not match what memory_tree_ingest expects); a genuine failure inside the memory canonicalizer for one thread.","commonSituations":"Running the script against a core built with different features (gated controllers are unknown-method per the repo's DomainSet/feature model); core and script versions drifted after a pull; malformed or truncated fixture JSON at argv[2].","solutions":["Read the embedded message — it is the core's authoritative error text for the failing call","List what the core actually serves: GET /schema on the same base URL and diff the namespace/method","Validate the fixture (argv[2], default tests/fixtures/memory/composio_gmail_inbox.json) parses and has messages[] with id/threadId/markdown","If the method is feature-gated, start the core with the required features and retry"],"exampleFix":"# before — edited script uses a method the core does not serve\nawait rpc('openhuman.memory_ingest_email', payload)   // -32601 unknown method\n\n# after — check /schema, then use the real method\n curl -s 'http://127.0.0.1:7810/schema' | jq -r '.[] | .namespace'   # confirm 'memory_tree' exists\nawait rpc('openhuman.memory_tree_ingest', payload)","handlingStrategy":"try-catch","validationCode":"const res = await fetch(RPC_URL, { method: 'POST', headers, body: JSON.stringify(req) });\nconst body = await res.json();\nif (body.error) { /* surface body.error.message — core-level failure, not transport */ }","typeGuard":"const isJsonRpcError = (b) => !!b && typeof b === 'object' && 'error' in b && !!b.error;","tryCatchPattern":"try { await rpc(method, params); }\ncatch (err) {\n  if (err.message.startsWith(`${method}: `)) { console.error('core error:', err.message); process.exitCode = 1; }\n  else throw err;\n}","preventionTips":["diff method names against GET /schema after core upgrades","validate fixture JSON shape before feeding RPC","treat unknown-method as a feature-gate/version mismatch first"],"tags":["jsonrpc","rpc-errors","testing","feature-gates"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}