affaan-m/ECC · error
must not contain duplicate values.
Error message
${label} must not contain duplicate values. What it means
uniqueStrings builds its result with a reduce that rejects any value whose normalized form already appeared earlier in the array, throwing this error. List fields in memory documents must be duplicate-free so tags/links/targets remain unambiguous.
Solutions
- Deduplicate before calling: Array.from(new Set(values)).
- Deduplicate on the normalized form (e.g. lowercase/trim each element first) so near-duplicates collapse.
- Fix the merge logic that appends items already present in the array.
- Check the error label to identify which list field contains the duplicate.
Example fix
// before
normalizeMemory({ tags: [...oldTags, ...newTags], ... })
// after
normalizeMemory({ tags: [...new Set([...oldTags, ...newTags])], ... }) Defensive patterns
Strategy: validation
Validate before calling
const dedupe = (arr) => Array.from(new Set(arr.map((s) => String(s).toLowerCase().trim())));
Type guard
const hasNoDuplicates = (v) => Array.isArray(v) && new Set(v).size === v.length;
Try / catch
try { normalizeMemory(mem); } catch (e) { if (e.message.includes('duplicate')) { mem.tags = dedupe(mem.tags); } else throw e; } Prevention
- Run new Set(values) on merged lists before saving
- Normalize case/whitespace before comparing for duplicates
- Make list-append operations idempotent
- Test merge helpers with overlapping inputs
When it happens
Trigger: Passing an array with the same value twice (after per-item validator normalization) to targetHarnesses, normalizeMemory, normalizeScopes, or kinds — e.g. tags: ['tdd', 'TDD'] if the validator lowercases, or an exact duplicate ['tdd', 'tdd'].
Common situations: Merging tag lists from two documents without deduplication; appending to an existing array on each script run; copy-pasting frontmatter where a tag appears in two groups; case differences that normalize to the same value.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- genre numbers must be distinct
- has too many values (maximum ).
- is too long (maximum characters).
- must be a lowercase letters/numbers slug.
- must be a non-empty string.
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/7af48005559c46eb.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/memory-vault-format.js:125
function validateMemoryId(value) {
const normalized = asNonEmptyString(value, 'memory id', 132);
if (!MEMORY_ID_PATTERN.test(normalized)) {
throw new Error('memory id must match mem_<lowercase-id> and cannot contain a path.');
}
return normalized;
}
function uniqueStrings(values, { label, limit, validator }) {
if (!Array.isArray(values)) {
throw new Error(`${label} must be an array.`);
}
if (values.length > limit) {
throw new Error(`${label} has too many values (maximum ${limit}).`);
}
return values.reduce((result, value) => {
const normalized = validator(value);
if (result.includes(normalized)) {
throw new Error(`${label} must not contain duplicate values.`);
}
return [...result, normalized];
}, []);
}
function validateTimestamp(value, label) {
const normalized = asNonEmptyString(value, label, 64);
const parsed = new Date(normalized);
if (
!ISO_TIMESTAMP_PATTERN.test(normalized)
|| Number.isNaN(parsed.getTime())
|| parsed.toISOString() !== normalized
) {
throw new Error(`${label} must be an ISO-8601 timestamp.`);
}
return normalized;
}
View on GitHub (pinned to 8321021c54)