thedotmack/claude-mem · error

Refusing CCS Align write to profile.md

Error message

Refusing CCS Align write to profile.md

What it means

assertSafeMiddleCachePath() additionally forbids writing to any file named profile.md within the ccs-align root. profile.md is a protected, separately-owned artifact (the awareness-log seam, cf. assertSafeAwarenessLogPath); landing observations over it would corrupt data managed by another subsystem, so the guard throws unconditionally on that basename.

Solutions

  1. Change the target filename to a non-reserved name (e.g. observations.md) before calling landObservationsInMiddleCache.
  2. Route profile.md writes through the dedicated profile/awareness API instead of the middle-cache writer.
  3. Add a caller-side check: if (path.basename(filePath) === 'profile.md') skip or rename.

Example fix

// before
const target = path.join(cacheDir, 'profile.md');

// after
const target = path.join(cacheDir, 'observations.md');
Defensive patterns

Strategy: validation

Validate before calling

import path from 'path';
if (path.basename(targetPath) === 'profile.md') {
  throw new Error('profile.md is protected; use the profile API');
}

Try / catch

try {
  landObservationsInMiddleCache(dataRoot, viewerId, filePath, observations);
} catch (err) {
  if (err instanceof Error && err.message.includes('profile.md')) {
    // route through the profile-update API instead of the cache writer
  } else throw err;
}

Prevention

When it happens

Trigger: landObservationsInMiddleCache() passes a filePath whose path.basename() is 'profile.md' — e.g. the cache filename was derived from a profile/observations key, or a constant pointed at profile.md instead of an observations file.

Common situations: A config or map keyed by file type routes profile data through the observation-write path; a filename template like '<name>.md' is fed 'profile'; two features share a file-naming convention and one targets the protected profile artifact.

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


AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17). Data as JSON: /api/errors/9ee0a08b9cb36592. Report an issue: GitHub.

Appendix: source

Thrown at src/services/integrations/CcsAlignMiddleCache.ts:286

    }
  }
  return { excludedObsIds, excludedToolUseIds };
}

/**
 * Refuse any write that escapes the seat-owned CCS Align root, targets
 * `profile.md`, or lands inside an `agents/.../memory/log` tree (that is the
 * #3931 pusher's seam, never Align's). Shape copied from
 * `assertSafeAwarenessLogPath` (#3931).
 */
export function assertSafeMiddleCachePath(dataRoot: string, viewerId: string, filePath: string): void {
  const expectedRoot = path.resolve(ccsAlignViewerDir(dataRoot, viewerId));
  const resolved = path.resolve(filePath);
  if (!resolved.startsWith(expectedRoot + path.sep) && resolved !== expectedRoot) {
    throw new Error('Refusing CCS Align write outside the seat-owned ccs-align root');
  }
  if (path.basename(resolved) === 'profile.md') {
    throw new Error('Refusing CCS Align write to profile.md');
  }
  if (/(^|[\\/])agents[\\/].*[\\/]memory[\\/]log([\\/]|$)/.test(resolved)) {
    throw new Error('Refusing CCS Align write into agents/**/memory/log (that seam belongs to #3931)');
  }
}

export function buildCcsAlignRecord(obs: CcsAlignObservationInput, now: Date = new Date()): CcsAlignMiddleRecord {
  return {
    v: RECORD_VERSION,
    id: obs.id,
    type: obs.type,
    title: obs.title ?? null,
    created_at: obs.created_at ?? null,
    project: obs.project ?? null,
    agent_id: obs.agent_id ?? null,
    source: obs.source ?? 'worker',
    line: formatCcsAlignLine(obs, now),
  };

View on GitHub (pinned to d8bc9755e7)