thedotmack/claude-mem · error
Refusing awareness write to profile.md
Error message
Refusing awareness write to profile.md
What it means
Within assertSafeAwarenessLogPath(), any awareness write whose target basename is profile.md is rejected outright. profile.md is a protected agent artifact managed by a different subsystem; the awareness pusher (append-only log lines) must never overwrite it, so the guard throws unconditionally on that filename.
Solutions
- Point the awareness write at the log file (e.g. awareness.md) instead of profile.md.
- Use the dedicated profile-update API for profile content rather than the awareness pusher.
- Add a caller-side guard: if (path.basename(logPath) === 'profile.md') skip or redirect the write.
Example fix
// before const logPath = path.join(agentDir, 'memory', 'log', 'profile.md'); // after const logPath = path.join(agentDir, 'memory', 'log', 'awareness.md');
Defensive patterns
Strategy: validation
Validate before calling
import path from 'path';
if (path.basename(logPath) === 'profile.md') {
throw new Error('profile.md is protected; use the profile API');
} Try / catch
try {
notifyGrokBotAwareness(agentDataRoot, agentId, logPath, line);
} catch (err) {
if (err instanceof Error && err.message.includes('profile.md')) {
// redirect to the profile-update flow instead of the awareness pusher
} else throw err;
} Prevention
- Use a dedicated constant for the awareness log filename; never reuse the profile filename.
- Centralize RESERVED_FILENAMES checks across all agent-writer helpers.
- Send profile changes through the profile API, not append-style awareness writes.
When it happens
Trigger: notifyGrokBotAwareness() is given a logPath ending in profile.md — e.g. an awareness key mapped to 'profile', a shared filename constant reused across features, or a caller confusing the awareness log with the profile file.
Common situations: A routing map that sends both 'profile' and 'log' events through the awareness pusher; refactored constants where AWARENESS_LOG was accidentally set to profile.md; a caller intending to update the profile via the wrong API.
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 CCS Align write to profile.md
- INVALID_CORPUS_NAME
- Refusing awareness write outside agent memory/log
- Refusing CCS Align write outside the seat-owned ccs-align…
- Adapter rejected input
AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17).
Data as JSON: /api/errors/bd8fabcb538e4f60.
Report an issue: GitHub.
Appendix: source
Thrown at src/services/integrations/GrokBotAwarenessPusher.ts:104
export function awarenessLineBody(line: string): string {
const idx = line.indexOf(AWARENESS_TAG);
return idx >= 0 ? line.slice(idx).trim() : line.trim();
}
export function grokBotAwarenessLogPath(agentDataRoot: string, agentId: string, now: Date = new Date()): string {
const yearMonth = now.toISOString().slice(0, 7);
return path.join(agentDataRoot, 'agents', agentId, 'memory', 'log', `${yearMonth}.md`);
}
function assertSafeAwarenessLogPath(agentDataRoot: string, agentId: string, logPath: string): void {
const expectedRoot = path.resolve(path.join(agentDataRoot, 'agents', agentId, 'memory', 'log'));
const resolved = path.resolve(logPath);
if (!resolved.startsWith(expectedRoot + path.sep) && resolved !== expectedRoot) {
throw new Error('Refusing awareness write outside agent memory/log');
}
if (path.basename(resolved) === 'profile.md') {
throw new Error('Refusing awareness write to profile.md');
}
}
export function appendAwarenessLineAtomic(logPath: string, line: string): boolean {
const dir = path.dirname(logPath);
mkdirSync(dir, { recursive: true });
const existing = existsSync(logPath) ? readFileSync(logPath, 'utf8') : '';
const incomingBody = awarenessLineBody(line);
const alreadyPresent = existing
.split('\n')
.some(existingLine => existingLine.trim() && awarenessLineBody(existingLine) === incomingBody);
if (alreadyPresent) {
return false;
}
const prefix = existing.length === 0 || existing.endsWith('\n') ? existing : `${existing}\n`;
const next = `${prefix}${line}\n`;View on GitHub (pinned to d8bc9755e7)