thedotmack/claude-mem · error
Refusing inject write to a file this writer does not own
Error message
Refusing inject write to a file this writer does not own: ${path.basename(resolved)} What it means
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.
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).
Example fix
// before writeFileAtomic(path.join(logDir, 'inject.md.tmp'), data); // after writeFileAtomic(injectLogPath(root, agentId), data);
Defensive patterns
Strategy: validation
Validate before calling
if (path.basename(path.resolve(target)) !== INJECT_LOG_BASENAME) {
throw new Error('writer only owns ' + INJECT_LOG_BASENAME);
} Try / catch
try {
assertSafeInjectPath(root, agentId, target);
writeFileAtomic(target, data);
} catch (err) {
if (String(err).startsWith('Refusing inject write')) logger.warn('Not the owned file', { target });
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Refusing write to profile.md
- Access denied: " " resolves outside the workspace ( ). MCP…
- Bun installation completed but binary not found. Please…
- Cannot lazy-spawn worker: Bun runtime not found on PATH
- Claude executable not found. Please either: 1. Add "claude"…
AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17).
Data as JSON: /api/errors/3a811130d9fc4023.
Report an issue: GitHub.
Appendix: source
Thrown at src/services/integrations/grok-bot-index-format.ts:178
export function injectLogPath(agentDataRoot: string, agentId: string): string {
if (!AGENT_ID_RE.test(agentId)) {
throw new Error(`Refusing inject path for non-UUID agent id: ${agentId}`);
}
return path.join(agentDataRoot, 'agents', agentId, 'memory', 'log', INJECT_LOG_BASENAME);
}
export function assertSafeInjectPath(agentDataRoot: string, agentId: string, filePath: string): void {
const expectedDir = path.resolve(path.join(agentDataRoot, 'agents', agentId, 'memory', 'log'));
const resolved = path.resolve(filePath);
if (path.basename(resolved).toLowerCase() === 'profile.md') {
throw new Error('Refusing write to profile.md');
}
if (path.dirname(resolved) !== expectedDir) {
throw new Error('Refusing inject write outside agent memory/log');
}
if (path.basename(resolved) !== INJECT_LOG_BASENAME) {
throw new Error(`Refusing inject write to a file this writer does not own: ${path.basename(resolved)}`);
}
}
function writeFileAtomic(filePath: string, contents: string): void {
mkdirSync(path.dirname(filePath), { recursive: true });
const tmp = `${filePath}.tmp-${process.pid}-${Date.now()}`;
writeFileSync(tmp, contents, 'utf8');
renameSync(tmp, filePath);
}
export function writeFileIfChanged(filePath: string, contents: string): { changed: boolean; filePath: string } {
if (existsSync(filePath) && readFileSync(filePath, 'utf8') === contents) {
return { changed: false, filePath };
}
writeFileAtomic(filePath, contents);
return { changed: true, filePath };
}
View on GitHub (pinned to d8bc9755e7)