{"record":{"id":"78199e1b806a224c","repo":"nexu-io/open-design","slug":"ingestion-body-is-required","errorCode":null,"errorMessage":"ingestion body is required","messagePattern":"ingestion body is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/daemon/src/automation-ingestions.ts","lineNumber":370,"sourceCode":"  packet: AutomationContentPacket,\n): Promise<void> {\n  const packets = await listAutomationSourcePackets(dataDir);\n  const next = packets.filter((existing) => existing.id !== packet.id);\n  next.push(packet);\n  await writePackets(dataDir, next);\n}\n\nfunction jsonObjectFrom(value: unknown): Record<string, JsonValue> {\n  if (!value || typeof value !== 'object' || Array.isArray(value)) return {};\n  return value as Record<string, JsonValue>;\n}\n\nexport async function ingestAutomationSource(\n  dataDir: string,\n  input: CreateAutomationSourceIngestionRequest,\n): Promise<AutomationSourceIngestionResponse> {\n  if (!input || typeof input !== 'object') {\n    throw new Error('ingestion body is required');\n  }\n  const sourceKind = sourceKindFrom(input.sourceKind);\n  const bodyMarkdown = typeof input.bodyMarkdown === 'string' ? input.bodyMarkdown.trim() : '';\n  if (!bodyMarkdown) throw new Error('bodyMarkdown is required');\n\n  const template = input.templateId ? await getAnyAutomationTemplate(dataDir, input.templateId) : null;\n  const templateSinks = template?.outputSinks ?? ['memory'];\n  const candidateSinks = outputSinksFrom(input.candidateSinks, templateSinks);\n  const reviewPolicy = reviewPolicyFrom(input.reviewPolicy, template?.reviewPolicy ?? 'always');\n  const tokenCompression = compressionModeFrom(\n    input.tokenCompression,\n    template?.tokenCompression ?? 'balanced',\n  );\n  const packetId = `packet_${randomUUID()}`;\n  const sourceEventId = `source_event_${randomUUID()}`;\n  const capturedAt = new Date().toISOString();\n  const sourceRef =\n    optionalString(input.sourceRef) ??","sourceCodeStart":352,"sourceCodeEnd":388,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/automation-ingestions.ts#L352-L388","documentation":"Thrown by ingestAutomationSource() when the input argument is falsy or not an object. It is the top-level body-presence guard that runs before any field is read; subsequent field errors (sourceKind, bodyMarkdown) cannot fire until this passes.","triggerScenarios":"Calling ingestAutomationSource() (or POSTing to the ingestion endpoint) with null, undefined, a primitive, or a string body that was not parsed into an object. Also reached if an upstream handler forgot to JSON.parse the request body.","commonSituations":"Express route missing express.json() middleware so req.body is undefined; client sending a plain-text body with the wrong content-type; programmatic caller passing a raw JSON string instead of a parsed object.","solutions":["Ensure the HTTP layer parses JSON bodies before invoking ingestAutomationSource.","Pass a parsed object literal, not a JSON string.","Confirm the client sends Content-Type: application/json with an object body."],"exampleFix":"// before\nawait ingestAutomationSource(dataDir, JSON.stringify({ sourceKind: 'upload', bodyMarkdown: '...' }));\n// after\nawait ingestAutomationSource(dataDir, { sourceKind: 'upload', bodyMarkdown: '...' });","handlingStrategy":"type-guard","validationCode":"if (!input || typeof input !== 'object') {\n  throw new Error('ingestion body is required');\n}","typeGuard":"function isIngestionBody(value: unknown): value is Record<string, unknown> {\n  return !!value && typeof value === 'object' && !Array.isArray(value);\n}","tryCatchPattern":null,"preventionTips":["Apply express.json() (or equivalent) middleware so req.body is a parsed object.","Pass parsed objects to ingestAutomationSource; never a JSON string.","Confirm Content-Type: application/json on the client."],"tags":["automation","ingestion","validation","api","daemon"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}