usememos/memos · error
missing required request body "body"
Error message
missing required request body "body"
What it means
Thrown by the MCP-to-OpenAPI adapter in server/router/mcp/adapter.go when an OpenAPI operation declares a required request body but the MCP tool call arguments do not include a "body" key (or it is JSON null). The adapter maps MCP tool arguments onto an HTTP request; a required body must arrive as arguments["body"]. The error surfaces to the MCP client as a tool error result.
Source
Thrown at server/router/mcp/adapter.go:72
if parameter.In != "query" {
continue
}
value, ok := arguments[parameter.Name]
if !ok || value == nil {
continue
}
query.Set(parameter.Name, valueToString(value))
}
if encoded := query.Encode(); encoded != "" {
path += "?" + encoded
}
var body io.Reader
if operation.RequestBody != nil {
bodyValue, ok := arguments["body"]
if !ok || bodyValue == nil {
if operation.RequestBody.Required {
return nil, errors.New(`missing required request body "body"`)
}
bodyValue = map[string]any{}
}
data, err := json.Marshal(bodyValue)
if err != nil {
return nil, errors.Wrap(err, "failed to marshal request body")
}
body = bytes.NewReader(data)
}
req := httptest.NewRequest(operation.Method, path, body).WithContext(ctx)
if body != nil {
req.Header.Set("Content-Type", "application/json")
}
if authorization != "" {
req.Header.Set("Authorization", authorization)
}View on GitHub (pinned to 14d757ce1f)
Solutions
- Include a "body" object in the tool call arguments matching the operation's request schema, e.g. {"body": {"content": "...", "visibility": "PRIVATE"}}
- Check the tool's input schema (derived from the OpenAPI spec) to confirm the body shape before invoking
- If the operation should accept an empty payload, fix the OpenAPI definition so requestBody is not required
Example fix
// before (MCP tool call)
await client.callTool({ name: "memos_createMemo", arguments: {} });
// after
await client.callTool({ name: "memos_createMemo", arguments: { body: { content: "hello" } } }); Defensive patterns
Strategy: validation
Validate before calling
// Before calling the MCP tool, confirm the operation requires a body and include it.
const requiresBody = operation.requestBody?.required === true;
const args = { ...toolArgs };
if (requiresBody && (args.body === undefined || args.body === null)) {
throw new Error(`Tool ${operation.operationId} requires a "body" argument`);
} Type guard
const hasRequiredBody = (args: Record<string, unknown>): boolean => args.body !== undefined && args.body !== null;
Try / catch
// The adapter returns tool errors inside CallToolResult (isError), not as thrown errors:
const result = await client.callTool({ name, arguments });
if (result.isError) {
const text = result.content?.[0]?.text ?? "";
if (text.includes('missing required request body')) {
// re-invoke with a body built from the tool's input schema
}
} Prevention
- Always inspect the tool's inputSchema before invoking; keep request payload under a "body" key
- When generating tool calls from LLM output, validate arguments against inputSchema first
When it happens
Trigger: Calling an MCP tool derived from a POST/PUT/PATCH OpenAPI operation whose requestBody.required is true without supplying the "body" argument, or passing body: null in the tool arguments.
Common situations: LLM agents omitting the body object for create/update tools; tool schemas that describe body properties at the top level instead of nested under "body"; optional-looking tool arguments for endpoints that actually require a payload.
Related errors
- SMTP host is required
- SMTP port must be between 1 and 65535
- from email is required
- filter expression is empty
- filter must evaluate to a boolean value
AI-assisted analysis of usememos/memos@14d757ce1f (2026-08-15).
Data as JSON: /api/errors/b7b1b3292d4c28c1.
Report an issue: GitHub.