{"record":{"id":"76d1d93fd780ccdd","repo":"affaan-m/ECC","slug":"refusing-to-save-memory-containing-a-suspected-sec","errorCode":null,"errorMessage":"Refusing to save memory containing a suspected secret (${secretKinds.join(', ')}).","messagePattern":"Refusing to save memory containing a suspected secret \\((.+?)\\)\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"scripts/lib/memory-vault.js","lineNumber":324,"sourceCode":"    scope: input.scope || 'project',\n    trust: 'unreviewed',\n    status: 'active',\n    sourceHarness: input.sourceHarness || 'unknown',\n    targetHarnesses: input.targetHarnesses || ['all'],\n    tags: input.tags || [],\n    links: input.links || [],\n    createdAt: now,\n    updatedAt: now,\n    body: input.body || '',\n  });\n}\n\nfunction saveMemory(input, options = {}) {\n  const roots = options.roots || resolveVaultRoots(options);\n  const memory = normalizeSaveInput(input || {}, options);\n  const secretKinds = findPotentialSecrets(JSON.stringify(memory));\n  if (secretKinds.length > 0) {\n    throw new Error(`Refusing to save memory containing a suspected secret (${secretKinds.join(', ')}).`);\n  }\n\n  const root = assertMemoryRootSafe(roots, memory.scope);\n  fs.mkdirSync(root, { recursive: true, mode: 0o700 });\n  ensureProjectScopeIgnored(roots, memory.scope);\n  const directory = path.join(root, `${memory.kind}s`);\n  assertMemoryDirectorySafe(directory, root);\n  fs.mkdirSync(directory, { recursive: true, mode: 0o700 });\n  const destination = path.join(directory, `${memory.id}.md`);\n\n  try {\n    writeCreateOnlyTextFile(destination, serializeMemoryDocument(memory), root);\n  } catch (error) {\n    if (error && error.code === 'EEXIST') {\n      throw new Error(`Memory ${memory.id} already exists; writes are create-only.`);\n    }\n    throw error;\n  }","sourceCodeStart":306,"sourceCodeEnd":342,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/memory-vault.js#L306-L342","documentation":"saveMemory serializes the memory payload to JSON and runs a secret scanner (findPotentialSecrets) before writing. If the payload matches patterns for API keys, tokens, passwords, or similar, the save is refused outright — a fail-closed guard so secrets never land in memory files that might be synced or committed.","triggerScenarios":"Calling saveMemory (directly or via runWriteCommand/saveWithId) with any field whose stringified content matches a secret heuristic: e.g. a value like 'sk-...', 'Bearer <token>', 'password=...', PEM keys, AWS keys.","commonSituations":"Saving a memory that quotes an .env snippet or API key for later reference; a code snippet embedded in the memory contains a hardcoded credential; CI tokens accidentally pasted into notes.","solutions":["Remove the secret from the memory content; store a reference/pointer instead of the credential.","Redact the sensitive value (e.g. 'sk-***') before saving.","Store the secret in a proper secret manager and save only its identifier in the memory.","If it is a false positive, rephrase the content so it no longer matches the secret patterns."],"exampleFix":"// before\nsaveMemory({ id: 'deploy-note', content: 'use API_KEY=sk-live-abc123' });\n// after\nsaveMemory({ id: 'deploy-note', content: 'use API_KEY from secret manager (entry: deploy/api-key)' });","handlingStrategy":"validation","validationCode":"const SECRET_PATTERNS = [/sk-[A-Za-z0-9]{20,}/, /AKIA[0-9A-Z]{16}/, /-----BEGIN [A-Z ]*PRIVATE KEY-----/, /Bearer\\s+[A-Za-z0-9._\\-]{20,}/, /(?:password|passwd|secret|token)\\s*[=:]\\s*\\S+/i];\nconst found = SECRET_PATTERNS.filter(re => re.test(JSON.stringify(memory)));\nif (found.length) throw new Error('Memory content contains a suspected secret; redact before saving.');","typeGuard":null,"tryCatchPattern":"try {\n  saveMemory(memory);\n} catch (err) {\n  if (err.message.startsWith('Refusing to save memory containing a suspected secret')) {\n    // redact the matched content and retry\n  } else throw err;\n}","preventionTips":["Never paste credentials, tokens, or .env contents into memory payloads.","Use secret references (vault entry names) instead of values.","Run your own secret scan on content before saving in pipelines.","If rotation is possible, rotate anything that was attempted to be saved."],"tags":["secrets","security","validation","memory-vault"],"backgroundTag":"secret-detected","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"}