Yeachan-Heo/oh-my-codex · error · Error

mode must not contain ".."

Error message

mode must not contain ".."

What it means

Thrown when the trimmed mode string contains ".." anywhere. Because mode is concatenated into filesystem paths, ".." would allow directory traversal in the state directory, so it is explicitly banned.

Source

Thrown at src/mcp/state-paths.ts:139

    throw new Error('session_id must be a string');
  }
  if (!SESSION_ID_PATTERN.test(sessionId)) {
    throw new Error('session_id must match ^[A-Za-z0-9_-]{1,64}$');
  }
  return sessionId;
}


export function validateStateModeSegment(mode: unknown): string {
  if (typeof mode !== 'string') {
    throw new Error('mode must be a string');
  }
  const normalized = mode.trim();
  if (!normalized) {
    throw new Error('mode must be a non-empty string');
  }
  if (normalized.includes('..')) {
    throw new Error('mode must not contain ".."');
  }
  if (normalized.includes('/') || normalized.includes('\\')) {
    throw new Error('mode must not contain path separators');
  }
  if (!STATE_MODE_SEGMENT_PATTERN.test(normalized)) {
    throw new Error('mode must match ^[A-Za-z0-9_-]{1,64}$');
  }
  return normalized;
}

export function getStateFilename(mode: string): string {
  return `${validateStateModeSegment(mode)}${STATE_FILE_SUFFIX}`;
}

export function validateStateFileName(fileName: unknown): string {
  if (typeof fileName !== 'string') {
    throw new Error('fileName must be a string');
  }

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Remove the double dots: use single dots only — note dots are rejected by the final pattern anyway, prefer hyphens
  2. Use "a-b" style separators instead of ".."
  3. Reject user input containing '..' before it reaches state APIs

Example fix

// before
getStateFilename("run..final");
// after
getStateFilename("run-final");
Defensive patterns

Strategy: validation

Validate before calling

if (mode.includes('..')) mode = mode.replace(/\.\./g, '-');

Type guard

function hasNoTraversal(v: string): boolean { return !v.includes('..'); }

Prevention

When it happens

Trigger: mode: "a..b", mode: "..", mode: "team..night" — any occurrence of two consecutive dots, even innocuous ones inside a word.

Common situations: Ellipsis-style naming ("draft..final"); attempts at traversal from untrusted input; accidental double-dot typos.

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 Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27). Data as JSON: /api/errors/9fdf62820e05791e. Report an issue: GitHub.