{"record":{"id":"437fec94758fd1a2","repo":"affaan-m/ECC","slug":"memory-must-be-an-object","errorCode":null,"errorMessage":"memory must be an object.","messagePattern":"memory must be an object\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/memory-vault-format.js","lineNumber":163,"sourceCode":"  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) {\n    throw new Error('target harnesses must contain at least one harness or \"all\".');\n  }\n\n  if (memory.schema !== MEMORY_SCHEMA_VERSION) {\n    throw new Error('Unsupported memory schema.');\n  }\n\n  return {\n    schema: memory.schema,\n    id: validateMemoryId(memory.id),","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/memory-vault-format.js#L145-L181","documentation":"normalizeMemory() validates that the memory argument passed to save/normalize is a plain, non-null, non-array object before applying field-level validation. The memory vault format requires an object mapping named fields (schema, id, title, targetHarnesses, etc.), so anything else — null, undefined, strings, arrays — is rejected early with this clear message instead of producing cryptic failures downstream.","triggerScenarios":"Calling normalizeMemory (directly or via normalizeSaveInput / parseMemoryDocument callers / normalized) with null, undefined, a string, a number, an array (e.g. JSON.parse('[...]')), or a Map/Set instead of a plain object.","commonSituations":"Piping JSON output from another tool where the top level is an array; forgetting to await a promise so a non-object flows in; passing null as a default; destructuring mistakes that yield undefined; scripts that read an empty file and pass '' as the memory.","solutions":["Wrap the memory payload in an object literal with the required fields (schema, id, title, targetHarnesses, ...).","Check the input source: if it came from JSON.parse, confirm the top-level value is an object, not an array or scalar.","Add a guard before the call: if (!memory || typeof memory !== 'object' || Array.isArray(memory)) handle the error case.","If using `null` as a sentinel for 'no memory', branch before calling normalize instead of passing null through."],"exampleFix":"// before\nconst memory = await loadMemory();\nawait saveMemory(memory); // loadMemory() may return null\n\n// after\nconst memory = await loadMemory() ?? { schema: MEMORY_SCHEMA_VERSION, id: 'default', title: 'Untitled', targetHarnesses: ['all'] };\nif (memory && typeof memory === 'object' && !Array.isArray(memory)) {\n  await saveMemory(memory);\n}","handlingStrategy":"type-guard","validationCode":"function isPlainObject(v) { return v !== null && typeof v === 'object' && !Array.isArray(v); }\nif (!isPlainObject(input)) throw new TypeError('memory payload must be a plain object');","typeGuard":"const isMemoryInput = (v) => v !== null && typeof v === 'object' && !Array.isArray(v);","tryCatchPattern":"try {\n  const memory = normalizeMemory(input);\n} catch (err) {\n  if (err.message === 'memory must be an object.') {\n    console.error('Refusing to save: memory payload is not an object (got %s).', input === null ? 'null' : typeof input);\n  } else throw err;\n}","preventionTips":["Validate JSON.parse output shape before passing it to the memory API.","Never pass `null` as a default memory value; branch before the call.","Check that file/stdin sources parse to an object, not an array or scalar."],"tags":["validation","type-mismatch","input-validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}