{"record":{"id":"d4896ea5aaa61258","repo":"affaan-m/ECC","slug":"memory-search-query-must-not-contain-control-chara","errorCode":null,"errorMessage":"memory search query must not contain control characters.","messagePattern":"memory search query must not contain control characters\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/memory-vault.js","lineNumber":608,"sourceCode":"  const start = Math.max(0, (matchIndex < 0 ? 0 : matchIndex) - 60);\n  const prefix = start > 0 ? '…' : '';\n  const suffix = start + maxChars < normalized.length ? '…' : '';\n  return `${prefix}${normalized.slice(start, start + maxChars)}${suffix}`;\n}\n\nfunction summarizeMemory(memory) {\n  return Object.fromEntries(\n    Object.entries(memory).filter(([key]) => key !== 'body')\n  );\n}\n\nfunction searchMemories(query, options = {}) {\n  const normalizedQuery = typeof query === 'string' ? query.trim() : '';\n  if (normalizedQuery.length > MAX_QUERY_CHARS) {\n    throw new Error(`memory search query is too long (maximum ${MAX_QUERY_CHARS} characters).`);\n  }\n  if (hasUnsafeControlCharacters(normalizedQuery)) {\n    throw new Error('memory search query must not contain control characters.');\n  }\n\n  const kinds = options.kinds\n    ? uniqueStrings(options.kinds, {\n      label: 'kinds',\n      limit: MEMORY_KINDS.length,\n      validator: value => validateEnum(value, MEMORY_KINDS, 'memory kind'),\n    })\n    : null;\n  const trust = options.trust\n    ? validateEnum(options.trust, MEMORY_TRUST_STATES, 'memory trust')\n    : null;\n  const targetHarness = options.targetHarness\n    ? validateSlug(options.targetHarness, 'target harness')\n    : null;\n  const limit = Math.max(1, Math.min(Number(options.limit) || 20, MAX_RESULTS));\n  const loaded = readMemoryFiles({ ...options, scopes: options.scopes || options.scope });\n","sourceCodeStart":590,"sourceCodeEnd":626,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/memory-vault.js#L590-L626","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nsearchMemories(rawClipboardText);\n// after\nconst query = rawClipboardText.replace(/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]/g, '').replace(/\\s+/g, ' ').trim();\nsearchMemories(query);","handlingStrategy":"validation","validationCode":"const hasUnsafeControlChars = (s) => /[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]/.test(s);\nif (hasUnsafeControlChars(query)) query = query.replace(/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]/g, ' ').replace(/\\s+/g, ' ').trim();","typeGuard":"const isCleanQuery = (q) => typeof q === 'string' && !/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]/.test(q);","tryCatchPattern":"try {\n  searchMemories(query);\n} catch (err) {\n  if (err.message.includes('control characters')) {\n    searchMemories(sanitizeQuery(query));\n  } else throw err;\n}","preventionTips":["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."],"tags":["validation","search","input-sanitization","memory-vault"],"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"}