affaan-m/ECC · error · Error
memory search query must not contain control characters.
Error message
memory search query must not contain control characters.
What it means
searchMemories rejects queries containing unsafe control characters (e.g. raw newlines, null bytes, escape sequences) via hasUnsafeControlCharacters. This prevents control-character injection into search processing and log/output corruption.
Solutions
- Strip control characters from the query before calling searchMemories.
- Collapse whitespace: replace newlines/tabs with spaces.
- Sanitize any programmatic input source before it reaches the query parameter.
Example fix
// before searchMemories(rawClipboardText); // after const query = rawClipboardText.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, '').replace(/\s+/g, ' ').trim(); searchMemories(query);
Defensive patterns
Strategy: validation
Validate before calling
const hasUnsafeControlChars = (s) => /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/.test(s); if (hasUnsafeControlChars(query)) query = query.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, ' ').replace(/\s+/g, ' ').trim();
Type guard
const isCleanQuery = (q) => typeof q === 'string' && !/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/.test(q);
Try / catch
try {
searchMemories(query);
} catch (err) {
if (err.message.includes('control characters')) {
searchMemories(sanitizeQuery(query));
} else throw err;
} Prevention
- Sanitize any clipboard/file/network input before it becomes a search query.
- Collapse whitespace and strip control characters at input boundaries.
- Test search paths with paste-heavy input in your tooling.
- Keep queries single-line in CLI integrations.
When it happens
Trigger: Calling searchMemories with a query containing control characters — often from copying multiline text, binary-ish input, or untrimmed terminal paste content into the query string.
Common situations: Pasting multi-line text (newlines/tabs count depending on the unsafe set) into a CLI search prompt; programmatic input from files or network responses not sanitized before search.
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
- memory search query is too long
- 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/d4896ea5aaa61258.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/memory-vault.js:608
const start = Math.max(0, (matchIndex < 0 ? 0 : matchIndex) - 60);
const prefix = start > 0 ? '…' : '';
const suffix = start + maxChars < normalized.length ? '…' : '';
return `${prefix}${normalized.slice(start, start + maxChars)}${suffix}`;
}
function summarizeMemory(memory) {
return Object.fromEntries(
Object.entries(memory).filter(([key]) => key !== 'body')
);
}
function searchMemories(query, options = {}) {
const normalizedQuery = typeof query === 'string' ? query.trim() : '';
if (normalizedQuery.length > MAX_QUERY_CHARS) {
throw new Error(`memory search query is too long (maximum ${MAX_QUERY_CHARS} characters).`);
}
if (hasUnsafeControlCharacters(normalizedQuery)) {
throw new Error('memory search query must not contain control characters.');
}
const kinds = options.kinds
? uniqueStrings(options.kinds, {
label: 'kinds',
limit: MEMORY_KINDS.length,
validator: value => validateEnum(value, MEMORY_KINDS, 'memory kind'),
})
: null;
const trust = options.trust
? validateEnum(options.trust, MEMORY_TRUST_STATES, 'memory trust')
: null;
const targetHarness = options.targetHarness
? validateSlug(options.targetHarness, 'target harness')
: null;
const limit = Math.max(1, Math.min(Number(options.limit) || 20, MAX_RESULTS));
const loaded = readMemoryFiles({ ...options, scopes: options.scopes || options.scope });
View on GitHub (pinned to 8321021c54)