thedotmack/claude-mem · error

Refusing inject path for non-UUID agent id

Error message

Refusing inject path for non-UUID agent id: ${agentId}

What it means

injectLogPath builds the filesystem path for an agent's inject log under agentDataRoot/agents/<agentId>/memory/log. It throws when agentId does not match AGENT_ID_RE (UUID format), preventing path injection or directory traversal through a crafted agent id.

Solutions

  1. Pass the agent's UUID as agentId (e.g. '550e8400-e29b-41d4-a716-446655440000'), matching AGENT_ID_RE.
  2. Look up the correct UUID from the agent registry if you only have a name or slug.
  3. Add a guard before calling: test the id against a UUID regex and reject or regenerate invalid ids.

Example fix

// before
const p = injectLogPath(root, agent.name); // 'my-grok-bot'
// after
const p = injectLogPath(root, agent.uuid); // '3f2504e0-4f89-11d3-9a0c-0305e82c3301'
Defensive patterns

Strategy: validation

Validate before calling

const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
if (!UUID_RE.test(agentId)) throw new Error(`bad agent id: ${agentId}`);
const p = injectLogPath(root, agentId);

Type guard

function isUuid(v: string): boolean {
  return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(v);
}

Try / catch

let p: string;
try {
  p = injectLogPath(root, agentId);
} catch (err) {
  logger.error('Non-UUID agent id, skipping inject log write', { agentId }, err);
  return;
}

Prevention

When it happens

Trigger: injectLogPath (via callers like filePath) is called with an agentId that is not a UUID — empty string, a project name, a path like '../x', or an id from an older data format.

Common situations: Legacy records store non-UUID agent ids; a caller passes a slug or display name instead of the UUID; corrupted DB rows or user-supplied ids flow into the memory writer.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


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

Appendix: source

Thrown at src/services/integrations/grok-bot-index-format.ts:163

export function renderIndexFile(factLines: string[]): string {
  return `${FILE_HEADER}${factLines.join('\n')}\n`;
}

export function factBlock(contents: string): string {
  return String(contents ?? '')
    .split('\n')
    .filter(line => line.startsWith('- ('))
    .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)}`);
  }
}

View on GitHub (pinned to d8bc9755e7)