thedotmack/claude-mem · error

observation_generation_status: "jobId" is required

Error message

observation_generation_status: "jobId" is required

What it means

Validation error inside the observation_generation_status tool handler. After the server-runtime guard passes, the handler normalizes jobId from args.jobId or args.job_id (snake-case alias), trims it, and throws this plain Error if the result is empty. This fires before ServerClient.getJobStatus() is called.

Source

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

    };
  }

  return callWorker('/api/context/inject', {
    query: {
      projects: projects.join(','),
      ...(args.platformSource !== undefined ? { platformSource: normalizeMcpPlatformSource(args.platformSource) } : {}),
      ...(args.full !== undefined ? { full: args.full } : {}),
      ...(args.colors !== undefined ? { colors: args.colors } : {}),
    },
    text: true,
  });
}

const handleObservationGenerationStatus = wrapHandler('observation_generation_status', async (args: ObservationGenerationStatusArgs) => {
  const ctx = requireServerForObservationTool('observation_generation_status');
  const jobId = (args?.jobId ?? args?.job_id ?? '').trim();
  if (!jobId) {
    throw new Error('observation_generation_status: "jobId" is required');
  }
  const response = await ctx.client.getJobStatus(jobId);
  return formatJsonResult(response);
});

async function ensureWorkerConnection(): Promise<boolean> {
  if (await verifyWorkerConnection()) {
    return true;
  }

  logger.warn('SYSTEM', 'Worker not available, attempting auto-start for MCP client');

  errorIfWorkerScriptMissing();

  try {
    const port = getWorkerPort();
    const result = await ensureWorkerStarted(port, WORKER_SCRIPT_PATH);
    if (result === 'dead') {

View on GitHub (pinned to d768ba3643)

Solutions

  1. Pass the job id returned by the generating call, using either jobId or job_id.
  2. If you have no job id, the generation either wasn't started (call recordEvent with generate !== false) or already completed; check the event response first.
  3. Store the returned job id immediately when you trigger generation so you can poll status.

Example fix

// before
await tools.observation_generation_status({});
// throws 'observation_generation_status: "jobId" is required'

// after
const { generationJob } = await tools.observation_record_event({
  eventType: 'session.end', generate: true,
});
await tools.observation_generation_status({ jobId: generationJob.id });
Defensive patterns

Strategy: validation

Validate before calling

const jobId = (args?.jobId ?? args?.job_id ?? '').toString().trim();
if (!jobId) {
  return { content: [{ type: 'text', text: 'jobId is required for observation_generation_status' }], isError: true };
}

Type guard

function hasJobId(v: unknown): v is { jobId: string } | { job_id: string } {
  const j = (v as any)?.jobId ?? (v as any)?.job_id;
  return typeof j === 'string' && j.trim().length > 0;
}

Prevention

When it happens

Trigger: Calling observation_generation_status with both jobId and job_id omitted/blank, or with a non-string that coerces to empty after trim. The handler accepts either camelCase or snake_case but both must be absent to fail.

Common situations: Caller lost the job id returned by a prior record_event with generate=true; passed an object id field that was undefined; copy-paste from a payload that used a different key name (e.g. 'id', 'generationJobId').

Related errors


AI-assisted analysis of thedotmack/claude-mem@d768ba3643 (2026-08-12). Data as JSON: /api/errors/055609fc8b318771. Report an issue: GitHub.