affaan-m/ECC · error · Error
memory body must contain non-whitespace context.
Error message
memory body must contain non-whitespace context.
What it means
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.
Source
Thrown at scripts/lib/memory-vault-format.js:153
!ISO_TIMESTAMP_PATTERN.test(normalized)
|| Number.isNaN(parsed.getTime())
|| parsed.toISOString() !== normalized
) {
throw new Error(`${label} must be an ISO-8601 timestamp.`);
}
return normalized;
}
function normalizeBody(value) {
if (typeof value !== 'string') {
throw new Error('memory body must be a string.');
}
if (hasUnsafeControlCharacters(value, true)) {
throw new Error('memory body must not contain unsafe control or bidirectional formatting characters.');
}
const normalized = value.trim();
if (normalized.length === 0) {
throw new Error('memory body must contain non-whitespace context.');
}
if (Buffer.byteLength(normalized, 'utf8') > MAX_BODY_BYTES) {
throw new Error(`memory body is too large (maximum ${MAX_BODY_BYTES} bytes).`);
}
return normalized;
}
function normalizeMemory(memory) {
if (!memory || typeof memory !== 'object' || Array.isArray(memory)) {
throw new Error('memory must be an object.');
}
const targetHarnesses = uniqueStrings(memory.targetHarnesses, {
label: 'target harnesses',
limit: MAX_TARGETS,
validator: value => validateSlug(value, 'target harness'),
});
if (targetHarnesses.length === 0) {View on GitHub (pinned to 01e15490f0)
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.
Example fix
// before
saveMemory({ title: 'session', body: '' }); // trimmed to length 0
// after
const body = (input.body || '').trim();
if (body.length === 0) throw new Error('Refusing to save empty memory.');
saveMemory({ title: 'session', body }); Defensive patterns
Strategy: validation
Validate before calling
if (typeof input.body !== 'string' || input.body.trim().length === 0) {
throw new Error('Refusing to save: body is required and must not be blank.');
}
saveMemory(input); Type guard
function isNonBlankBody(value): value is string {
return typeof value === 'string' && value.trim().length > 0;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- memory body must be a string.
- target harnesses must contain at least one harness or "all".
- Memory document ${sourcePath} is missing fields: ${missing.j
- --title is required.
- ${label} must be a non-empty string.
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/1e7703a81d0ee130.
Report an issue: GitHub.