{"record":{"id":"3a811130d9fc4023","repo":"thedotmack/claude-mem","slug":"refusing-inject-write-to-a-file-this-writer-does-not-own","errorCode":null,"errorMessage":"Refusing inject write to a file this writer does not own: ${path.basename(resolved)}","messagePattern":"Refusing inject write to a file this writer does not own: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/services/integrations/grok-bot-index-format.ts","lineNumber":178,"sourceCode":"\nexport function injectLogPath(agentDataRoot: string, agentId: string): string {\n  if (!AGENT_ID_RE.test(agentId)) {\n    throw new Error(`Refusing inject path for non-UUID agent id: ${agentId}`);\n  }\n  return path.join(agentDataRoot, 'agents', agentId, 'memory', 'log', INJECT_LOG_BASENAME);\n}\n\nexport function assertSafeInjectPath(agentDataRoot: string, agentId: string, filePath: string): void {\n  const expectedDir = path.resolve(path.join(agentDataRoot, 'agents', agentId, 'memory', 'log'));\n  const resolved = path.resolve(filePath);\n  if (path.basename(resolved).toLowerCase() === 'profile.md') {\n    throw new Error('Refusing write to profile.md');\n  }\n  if (path.dirname(resolved) !== expectedDir) {\n    throw new Error('Refusing inject write outside agent memory/log');\n  }\n  if (path.basename(resolved) !== INJECT_LOG_BASENAME) {\n    throw new Error(`Refusing inject write to a file this writer does not own: ${path.basename(resolved)}`);\n  }\n}\n\nfunction writeFileAtomic(filePath: string, contents: string): void {\n  mkdirSync(path.dirname(filePath), { recursive: true });\n  const tmp = `${filePath}.tmp-${process.pid}-${Date.now()}`;\n  writeFileSync(tmp, contents, 'utf8');\n  renameSync(tmp, filePath);\n}\n\nexport function writeFileIfChanged(filePath: string, contents: string): { changed: boolean; filePath: string } {\n  if (existsSync(filePath) && readFileSync(filePath, 'utf8') === contents) {\n    return { changed: false, filePath };\n  }\n  writeFileAtomic(filePath, contents);\n  return { changed: true, filePath };\n}\n","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/services/integrations/grok-bot-index-format.ts#L160-L196","documentation":"assertSafeInjectPath enforces that this writer only ever overwrites its own inject log file. Even inside the correct directory, a target whose basename is not INJECT_LOG_BASENAME is rejected, preventing accidental clobbering of sibling files in the agent memory/log directory.","triggerScenarios":"refreshSeatIndex or ensureIndexLogDir targets a file inside memory/log other than INJECT_LOG_BASENAME — e.g. 'summary.md', 'notes.log', or a date-suffixed filename built by the caller.","commonSituations":"Code generalized to write arbitrary log files reuses this guard; filename constants were renamed in one place but not another; callers append suffixes like '.bak' to the path.","solutions":["Use injectLogPath(agentDataRoot, agentId) to derive the exact owned filename instead of constructing it manually.","If you need to write a different file, use a general-purpose file writer rather than this guarded inject-log writer.","Check the constant INJECT_LOG_BASENAME and make sure your path uses exactly that basename (no suffixes)."],"exampleFix":"// before\nwriteFileAtomic(path.join(logDir, 'inject.md.tmp'), data);\n// after\nwriteFileAtomic(injectLogPath(root, agentId), data);","handlingStrategy":"validation","validationCode":"if (path.basename(path.resolve(target)) !== INJECT_LOG_BASENAME) {\n  throw new Error('writer only owns ' + INJECT_LOG_BASENAME);\n}","typeGuard":null,"tryCatchPattern":"try {\n  assertSafeInjectPath(root, agentId, target);\n  writeFileAtomic(target, data);\n} catch (err) {\n  if (String(err).startsWith('Refusing inject write')) logger.warn('Not the owned file', { target });\n}","preventionTips":["Always call injectLogPath() instead of hand-building filenames.","Do not add suffixes (.tmp, .bak) to the inject log path.","Route all other files to a general-purpose writer."],"tags":["path","write","safety"],"backgroundTag":"unsupported-operation","analyzedSha":"d8bc9755e74915e5c3b999181e10a67c889bce2a","analyzedAt":"2026-09-17T16:40:26.182Z","contentChangedAt":"2026-09-17T16:40:26.182Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}