thedotmack/claude-mem · warning · AppError

INVALID_CORPUS_NAME

INVALID_CORPUS_NAME

Error message

Invalid corpus name: only alphanumeric characters, dots, hyphens, and underscores are allowed

What it means

Thrown by CorpusStore.validateCorpusName when a corpus name (after trim) does not match /^[a-zA-Z0-9._-]+$/ . It is an AppError with HTTP 400 and code INVALID_CORPUS_NAME — a client-side input mistake, not a server fault. Names with spaces, slashes, or non-ASCII are rejected to keep file paths safe.

Source

Thrown at src/services/worker/knowledge/CorpusStore.ts:100

    return results;
  }

  delete(name: string): boolean {
    const filePath = this.getFilePath(name);
    if (!fs.existsSync(filePath)) {
      return false;
    }

    fs.unlinkSync(filePath);
    logger.debug('WORKER', `Deleted corpus file: ${filePath}`);
    return true;
  }

  private validateCorpusName(name: string): string {
    const trimmed = name.trim();
    if (!CORPUS_NAME_PATTERN.test(trimmed)) {
      throw new AppError(CORPUS_NAME_ERROR, 400, 'INVALID_CORPUS_NAME');
    }
    return trimmed;
  }

  private getFilePath(name: string): string {
    const safeName = this.validateCorpusName(name);
    const resolved = path.resolve(this.corporaDir, `${safeName}.corpus.json`);
    if (!resolved.startsWith(path.resolve(this.corporaDir) + path.sep)) {
      throw new AppError('Invalid corpus name', 400, 'INVALID_CORPUS_NAME');
    }
    return resolved;
  }
}

View on GitHub (pinned to d768ba3643)

Solutions

  1. Sanitize the name client-side to alphanumeric, '.', '-', '_' only before sending.
  2. Trim whitespace and replace spaces with hyphens or underscores.
  3. Validate against CORPUS_NAME_PATTERN (/^[a-zA-Z0-9._-]+$/) in the API layer and return a friendly 400 before reaching CorpusStore.

Example fix

// before
const name = userInput; // 'my corpus v2'
store.write({ name, ... });

// after
import { CORPUS_NAME_PATTERN } from './CorpusStore';
const name = userInput.trim().replace(/\s+/g, '-');
if (!CORPUS_NAME_PATTERN.test(name)) {
  throw new Error(`Invalid corpus name: ${name}`);
}
store.write({ name, ... });
Defensive patterns

Strategy: validation

Validate before calling

import { CORPUS_NAME_PATTERN } from './CorpusStore';
function isValidCorpusName(name: string): boolean {
  return CORPUS_NAME_PATTERN.test(name.trim());
}
if (!isValidCorpusName(name)) {
  return res.status(400).json({ error: 'Invalid corpus name' });
}

Type guard

function isCorpusName(name: string): boolean {
  return typeof name === 'string' && /^[a-zA-Z0-9._-]+$/.test(name.trim());
}

Try / catch

try {
  store.write(corpus);
} catch (err) {
  if (err instanceof AppError && err.code === 'INVALID_CORPUS_NAME') {
    return res.status(400).json({ error: err.message });
  }
  throw err;
}

Prevention

When it happens

Trigger: Any CorpusStore operation (write/read/list/delete) receiving a name containing spaces, '/', '\\', colons, or non-ASCII characters; e.g., POSTing a corpus with name 'my corpus' or 'a/b'.

Common situations: User-typed corpus name with a space; UI passing an untrimmed title; API client sending a path-like name; copy-paste introducing unicode dashes/quotes.

Related errors


AI-assisted analysis of thedotmack/claude-mem@d768ba3643 (2026-08-12). Data as JSON: /api/errors/51c38260c6eec7ad. Report an issue: GitHub.