thedotmack/claude-mem · error
Refusing write to profile.md
Error message
Refusing write to profile.md
What it means
assertSafeInjectPath validates a destination path before the memory writer writes to it. profile.md is a user-owned agent file that this writer must never modify, so any write target named profile.md (case-insensitive) is rejected outright.
Solutions
- Write to INJECT_LOG_BASENAME (the owned log file) inside agents/<agentId>/memory/log instead of profile.md.
- Update the calling code so profile content is handled by the profile-specific writer, not the inject-log writer.
- Check the resolved basename before calling and skip the write when it is profile.md.
Example fix
// before writeInject(root, agentId, path.join(dir, 'profile.md'), data); // after writeInject(root, agentId, injectLogPath(root, agentId), data);
Defensive patterns
Strategy: validation
Validate before calling
if (path.basename(path.resolve(target)).toLowerCase() === 'profile.md') {
throw new Error('use the profile writer, not the inject writer');
} Try / catch
try {
assertSafeInjectPath(root, agentId, target);
writeFileAtomic(target, data);
} catch (err) {
logger.error('Inject write rejected', { target }, err);
} Prevention
- Derive write targets only from injectLogPath().
- Keep profile.md managed by its dedicated writer.
- Never pass caller-supplied filenames into the inject writer.
When it happens
Trigger: refreshSeatIndex or ensureIndexLogDir computes a write path whose basename is profile.md — e.g. a caller passes the profile file instead of the inject-log basename into the write path guard.
Common situations: A caller confuses the inject log with the agent profile file; refactored code reuses the writer for profile updates; a dynamic filename ends up as 'Profile.md'.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- Refusing inject write to a file this writer does not own
- 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/2672549ca833a216.
Report an issue: GitHub.
Appendix: source
Thrown at src/services/integrations/grok-bot-index-format.ts:172
.join('\n');
}
export function shouldRewriteInject(existingContents: string, nextContents: string): boolean {
return factBlock(existingContents) !== factBlock(nextContents);
}
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) {View on GitHub (pinned to d8bc9755e7)