{"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/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/memory-vault-format.js#L145-L181","documentation":"Thrown by normalizeMemory() as its opening guard: the memory argument must be a non-null, non-array object. Because memory has 13 named fields, anything that is not a plain object cannot satisfy the schema. Arrays are explicitly excluded even though typeof [] === 'object', and null/undefined are caught together with primitives.","triggerScenarios":"normalizeMemory(null), normalizeMemory(undefined) from a lookup that returned nothing, normalizeMemory([]) when the caller forgot to destructure an array of memories, normalizeMemory(JSON.parse('\"string\"')) where JSON.parse returned a primitive, or normalizeMemory(42) from a numeric ID confusion.","commonSituations":"Reading from a JSON file whose top-level shape is an array rather than an object. Calling normalizeMemory(saveMemoryInput) inside a loop where one iteration forgot to build the object. Network deserialiser returning a string instead of an object on error.","solutions":["Always build the object literal explicitly with all required fields before calling normalizeMemory.","For inputs from JSON, validate shape first: if (!input || typeof input !== 'object' || Array.isArray(input)) return null;","Prefer the higher-level saveMemory() helper, which constructs the object for you via normalizeSaveInput.","Add a TypeScript input type so the mistake is a compile-time error."],"exampleFix":"// before\nconst memory = JSON.parse(rawText);           // could be array or primitive\nreturn normalizeMemory(memory);\n\n// after\nconst parsed = JSON.parse(rawText);\nif (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n  throw new Error('expected a memory object');\n}\nreturn normalizeMemory(parsed);","handlingStrategy":"type-guard","validationCode":"if (!input || typeof input !== 'object' || Array.isArray(input)) {\n  throw new TypeError('memory must be a plain object');\n}\nnormalizeMemory(input);","typeGuard":"function isMemoryObject(value): value is Record<string, unknown> {\n  return value !== null && typeof value === 'object' && !Array.isArray(value);\n}","tryCatchPattern":null,"preventionTips":["Prefer saveMemory() over normalizeMemory() — it builds the object for you.","Type the input as a specific interface, not 'any'.","Validate shape after JSON.parse() before passing into the library."],"tags":["type-check","validation","memory-vault"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}