{"record":{"id":"6135814ff536448f","repo":"affaan-m/ECC","slug":"target-harnesses-must-contain-at-least-one-harness","errorCode":null,"errorMessage":"target harnesses must contain at least one harness or \"all\".","messagePattern":"target harnesses must contain at least one harness or \"all\"\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/memory-vault-format.js","lineNumber":172,"sourceCode":"  }\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),\n    title: asNonEmptyString(memory.title, 'memory title', MAX_TITLE_CHARS),\n    kind: validateEnum(memory.kind, MEMORY_KINDS, 'memory kind'),\n    scope: validateEnum(memory.scope, MEMORY_SCOPES, 'memory scope'),\n    trust: validateEnum(memory.trust, MEMORY_TRUST_STATES, 'memory trust'),\n    status: validateEnum(memory.status, MEMORY_STATUSES, 'memory status'),\n    sourceHarness: validateSlug(memory.sourceHarness, 'source harness'),\n    targetHarnesses,\n    tags: uniqueStrings(memory.tags, {\n      label: 'tags',","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/memory-vault-format.js#L154-L190","documentation":"After normalizing memory.targetHarnesses through uniqueStrings (which also deduplicates, enforces a max count of MAX_TARGETS, and slug-validates each entry), normalizeMemory requires at least one target harness entry — or the special value 'all'. An empty list would make the memory invisible to every harness, so it is rejected.","triggerScenarios":"Saving a memory with targetHarnesses: [] (or omitting it so it resolves to an empty list), or passing targetHarnesses: ['all'] alongside invalid entries that are filtered out leaving zero valid harnesses.","commonSituations":"Hand-written frontmatter with `targetHarnesses: []`; tooling that strips invalid slugs and leaves an empty array; a config template where the harness list placeholder was never filled in.","solutions":["Include at least one harness slug in targetHarnesses, e.g. ['claude'] or ['claude', 'codex'].","Use ['all'] if the memory should apply to every harness.","Check that entries are valid slugs (validateSlug) — invalid entries may fail earlier or be filtered, leaving the list empty.","Verify the frontmatter field is present at all; a missing targetHarnesses field yields an empty normalized list."],"exampleFix":"// before\n{\n  schema: 1,\n  id: 'deploy-notes',\n  title: 'Deploy notes',\n  targetHarnesses: []\n}\n\n// after\n{\n  schema: 1,\n  id: 'deploy-notes',\n  title: 'Deploy notes',\n  targetHarnesses: ['all']\n}","handlingStrategy":"validation","validationCode":"const harnesses = Array.isArray(input.targetHarnesses)\n  ? input.targetHarnesses.filter(h => typeof h === 'string' && h.length > 0)\n  : [];\nif (harnesses.length === 0) input.targetHarnesses = ['all'];","typeGuard":"const hasTargetHarnesses = (m) => Array.isArray(m.targetHarnesses) && m.targetHarnesses.length > 0;","tryCatchPattern":"try {\n  saveMemory(memory);\n} catch (err) {\n  if (err.message.includes('target harnesses must contain at least one')) {\n    saveMemory({ ...memory, targetHarnesses: ['all'] });\n  } else throw err;\n}","preventionTips":["Default targetHarnesses to ['all'] in templates and constructors.","Never build the harness list by filtering without re-checking the result is non-empty.","Validate frontmatter targetHarnesses after hand edits."],"tags":["validation","empty-array","memory-vault"],"backgroundTag":"empty-required-field","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"}