pydantic/monty · error · Error

invalid mount mode: '${mode}'. Expected 'read-only', 'read-w

Error message

invalid mount mode: '${mode}'. Expected 'read-only', 'read-write' or 'overlay'

What it means

MountDir's mode option must be one of 'read-only', 'read-write' or 'overlay' (defaulting to 'overlay'). The constructor validates with Object.hasOwn against a whitelist — so prototype-inherited keys like 'toString' are also rejected — and throws this Error for anything else, before any directory is opened.

Source

Thrown at crates/monty-js/ts/mountDir.ts:51

 * const mount = new MountDir({ hostPath: '/path/on/host', virtualPath: '/mnt/data', mode: 'read-only' })
 * await session.feedRun("open('/mnt/data/file.txt').read()", { mount })
 * ```
 */
export class MountDir {
  readonly hostPath: string
  readonly virtualPath: string
  readonly mode: MountDirMode
  readonly writeBytesLimit: number | null
  readonly memoryUsageLimit: number
  /** The opened host directory, shared by every feed this mount is passed to.
   *  Symbol-keyed, so it stays off the public surface — see [`NATIVE_MOUNT`]. */
  readonly [NATIVE_MOUNT]: NativeMountDir

  constructor(options: MountDirOptions) {
    const mode = options.mode ?? 'overlay'
    // hasOwn, not `in`: prototype keys like 'toString' must not pass as modes
    if (!Object.hasOwn(VALID_MODES, mode)) {
      throw new Error(`invalid mount mode: '${mode}'. Expected 'read-only', 'read-write' or 'overlay'`)
    }
    this.hostPath = options.hostPath
    this.virtualPath = options.virtualPath
    this.mode = mode
    this.writeBytesLimit = options.writeBytesLimit ?? null
    this.memoryUsageLimit = options.memoryUsageLimit ?? DEFAULT_MEMORY_USAGE_LIMIT
    if (!Number.isSafeInteger(this.memoryUsageLimit) || this.memoryUsageLimit < 0) {
      throw new Error('memoryUsageLimit must be a non-negative safe integer')
    }
    // Opens the directory, so a bad host path throws here rather than at the
    // first feed — and every feed then mounts this descriptor, which no rename
    // of the host path can redirect.
    this[NATIVE_MOUNT] = new NativeMountDir({
      virtualPath: this.virtualPath,
      hostPath: this.hostPath,
      mode: this.mode,
      memoryUsageLimit: this.memoryUsageLimit,
      ...(this.writeBytesLimit !== null ? { writeBytesLimit: this.writeBytesLimit } : {}),

View on GitHub (pinned to adc986b362)

Solutions

  1. Use exactly 'read-only', 'read-write' or 'overlay' (or omit mode for the 'overlay' default)
  2. Normalize config-sourced modes to the kebab-case literals before constructing MountDir
  3. Map your app's own mode enum to the library's three valid values

Example fix

// before
new MountDir({ hostPath: './data', virtualPath: '/mnt/data', mode: 'readonly' });
// after
new MountDir({ hostPath: './data', virtualPath: '/mnt/data', mode: 'read-only' });
Defensive patterns

Strategy: validation

Validate before calling

const MOUNT_MODES = new Set(['read-only', 'read-write', 'overlay']);
if (mode !== undefined && !MOUNT_MODES.has(mode)) {
  throw new Error(`mode must be 'read-only', 'read-write' or 'overlay', got ${JSON.stringify(mode)}`);
}

Type guard

function isMountMode(v) {
  return v === undefined || v === 'read-only' || v === 'read-write' || v === 'overlay';
}

Try / catch

try {
  const dir = new MountDir({ hostPath, virtualPath, mode });
} catch (e) {
  if (e instanceof Error && e.message.includes('invalid mount mode')) {
    throw new Error(`fix mount mode in config; valid values: read-only, read-write, overlay`);
  }
  throw e;
}

Prevention

When it happens

Trigger: new MountDir({ hostPath, virtualPath, mode: 'rw' }) or any misspelled/aliased mode ('readonly', 'RO', 'write').

Common situations: Mode strings sourced from config files or environment variables with different naming conventions; abbreviations assumed supported; camelCase vs kebab-case confusion.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13). Data as JSON: /api/errors/7cfce03029b3e1ee. Report an issue: GitHub.