thedotmack/claude-mem · error

observation_record_event: "eventType" is required

Error message

observation_record_event: "eventType" is required

What it means

The observation_record_event MCP tool handler validates its arguments before forwarding them to the server. It throws this error when the 'eventType' argument is absent, not a string, or an empty/whitespace-only string. The library enforces this so events recorded via the observation pipeline always carry a valid event type.

Solutions

  1. Pass a non-empty string eventType, e.g. { eventType: 'user_prompt_submitted' }
  2. If the value comes from a variable, default it before calling: args.eventType?.trim() || fallbackEventType
  3. Check the tool's input schema (required: eventType) in the MCP client to catch it at call-construction time
  4. Ensure the caller is not passing snake_case job-style aliases; unlike jobId there is no fallback name for eventType

Example fix

// before
await callTool('observation_record_event', { projectId: 'p1', sourceType: 'api' });
// after
await callTool('observation_record_event', { projectId: 'p1', sourceType: 'api', eventType: 'tool_call_completed' });
Defensive patterns

Strategy: validation

Validate before calling

function canRecordEvent(args) {
  return typeof args?.eventType === 'string' && args.eventType.trim().length > 0;
}
if (!canRecordEvent(args)) throw new Error('eventType must be a non-empty string before calling observation_record_event');

Type guard

function hasEventType(args: unknown): args is { eventType: string } & Record<string, unknown> {
  return typeof (args as any)?.eventType === 'string' && (args as any).eventType.trim().length > 0;
}

Try / catch

try {
  return await callTool('observation_record_event', args);
} catch (e) {
  if (e instanceof Error && e.message.includes('"eventType" is required')) {
    console.error('Provide a non-empty eventType, e.g. tool_call_completed');
    return null;
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling the observation_record_event tool with args missing 'eventType', with eventType set to null/undefined, a non-string value, or a string like '' or ' ' (the handler checks typeof === 'string' && trim().length > 0).

Common situations: LLM clients invoking the tool without the eventType parameter; tool-call argument serialization dropping optional-looking fields; renaming eventType to type/event_type in caller code; template-generated calls where the variable was empty.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17). Data as JSON: /api/errors/2f69bc4bfbaf703f. Report an issue: GitHub.

Appendix: source

Thrown at src/servers/mcp-server.ts:282

  serverSessionId?: string | null;
  contentSessionId?: string | null;
  memorySessionId?: string | null;
  platformSource?: string | null;
  sourceType?: 'hook' | 'worker' | 'provider' | 'server' | 'api';
  eventType: string;
  payload?: unknown;
  occurredAtEpoch?: number;
  generate?: boolean;
}

function normalizeMcpPlatformSource(value: string | null): string | null {
  return typeof value === 'string' ? normalizePlatformSource(value) : null;
}

const handleObservationRecordEvent = wrapHandler('observation_record_event', async (args: ObservationRecordEventArgs) => {
  const ctx = requireServerForObservationTool('observation_record_event');
  if (typeof args?.eventType !== 'string' || args.eventType.trim().length === 0) {
    throw new Error('observation_record_event: "eventType" is required');
  }
  const projectId = args.projectId && args.projectId.trim().length > 0 ? args.projectId : ctx.projectId;
  const request: ServerRecordEventRequest = {
    projectId,
    sourceType: args.sourceType ?? 'api',
    eventType: args.eventType,
    occurredAtEpoch: typeof args.occurredAtEpoch === 'number' ? args.occurredAtEpoch : Date.now(),
    ...(args.serverSessionId !== undefined ? { serverSessionId: args.serverSessionId } : {}),
    ...(args.contentSessionId !== undefined ? { contentSessionId: args.contentSessionId } : {}),
    ...(args.memorySessionId !== undefined ? { memorySessionId: args.memorySessionId } : {}),
    ...(args.platformSource !== undefined ? { platformSource: normalizeMcpPlatformSource(args.platformSource) } : {}),
    ...(args.payload !== undefined ? { payload: args.payload } : {}),
    ...(args.generate !== undefined ? { generate: args.generate } : {}),
  };
  const response = await ctx.client.recordEvent(request);
  return formatJsonResult(response);
});

View on GitHub (pinned to d8bc9755e7)