{"record":{"id":"1e7703a81d0ee130","repo":"affaan-m/ECC","slug":"memory-body-must-contain-non-whitespace-context","errorCode":null,"errorMessage":"memory body must contain non-whitespace context.","messagePattern":"memory body must contain non-whitespace context\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/memory-vault-format.js","lineNumber":153,"sourceCode":"    !ISO_TIMESTAMP_PATTERN.test(normalized)\n    || Number.isNaN(parsed.getTime())\n    || parsed.toISOString() !== normalized\n  ) {\n    throw new Error(`${label} must be an ISO-8601 timestamp.`);\n  }\n  return normalized;\n}\n\nfunction normalizeBody(value) {\n  if (typeof value !== 'string') {\n    throw new Error('memory body must be a string.');\n  }\n  if (hasUnsafeControlCharacters(value, true)) {\n    throw new Error('memory body must not contain unsafe control or bidirectional formatting characters.');\n  }\n  const normalized = value.trim();\n  if (normalized.length === 0) {\n    throw new Error('memory body must contain non-whitespace context.');\n  }\n  if (Buffer.byteLength(normalized, 'utf8') > MAX_BODY_BYTES) {\n    throw new Error(`memory body is too large (maximum ${MAX_BODY_BYTES} bytes).`);\n  }\n  return normalized;\n}\n\nfunction normalizeMemory(memory) {\n  if (!memory || typeof memory !== 'object' || Array.isArray(memory)) {\n    throw new Error('memory must be an object.');\n  }\n\n  const targetHarnesses = uniqueStrings(memory.targetHarnesses, {\n    label: 'target harnesses',\n    limit: MAX_TARGETS,\n    validator: value => validateSlug(value, 'target harness'),\n  });\n  if (targetHarnesses.length === 0) {","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/memory-vault-format.js#L135-L171","documentation":"Thrown by normalizeBody() after value.trim() when the trimmed length is 0. The library treats a body of only whitespace as missing context — memories exist to carry information, and the body is the only free-form slot for it. Title, tags, and links cannot substitute for an actual body.","triggerScenarios":"saveMemory({body: '   '}), saveMemory({body: '\\n\\t\\n'}), saveMemory({}) when the caller's default body was an empty string but normalizeSaveInput forwards '' (note: normalizeSaveInput sets body: input.body || '' so the trim inside normalizeBody then rejects it), or saveMemory({body: '\\u200b'}) with only zero-width spaces.","commonSituations":"Save pipeline created from a form where the user left the body field blank. CLI tool that takes --body from argv but the flag was omitted. Wrapper that passes through an empty default. Auto-generated handoff memory that has no content because the prior step produced nothing.","solutions":["Require a non-empty body in your UI/CLI before calling saveMemory.","If body is legitimately optional in your flow, branch: only call saveMemory when body.trim() is non-empty.","Detect early: if (!input.body || !input.body.trim()) throw new Error('body required').","Generate a meaningful default body for automated memories rather than empty."],"exampleFix":"// before\nsaveMemory({ title: 'session', body: '' }); // trimmed to length 0\n\n// after\nconst body = (input.body || '').trim();\nif (body.length === 0) throw new Error('Refusing to save empty memory.');\nsaveMemory({ title: 'session', body });","handlingStrategy":"validation","validationCode":"if (typeof input.body !== 'string' || input.body.trim().length === 0) {\n  throw new Error('Refusing to save: body is required and must not be blank.');\n}\nsaveMemory(input);","typeGuard":"function isNonBlankBody(value): value is string {\n  return typeof value === 'string' && value.trim().length > 0;\n}","tryCatchPattern":null,"preventionTips":["Validate body presence in the UI form or CLI parser before constructing the saveMemory input.","If body is optional in your flow, branch and skip the save rather than passing an empty string.","Add a require-body assertion in your wrapper so the error message names your feature, not the library."],"tags":["validation","memory-vault","body","required-field"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}