pydantic/monty · error · TypeError

MontyFileHandle mode must be a string

Error message

MontyFileHandle mode must be a string

What it means

The `MontyFileHandle` constructor validates that the `mode` argument is a JavaScript string. The mode is the Python-style open mode (e.g. 'r', 'w', 'rb') which is canonicalized character by character, so non-string values cannot be accepted.

Source

Thrown at crates/monty-js/ts/types.ts:85

/**
 * Host-side handle to a file opened inside a Monty sandbox.
 *
 * This is a plain data holder, never a live host file descriptor. Return one
 * from an `open` OS callback so Monty can construct its sandboxed file object.
 */
export class MontyFileHandle {
  /** Virtual POSIX sandbox path, never a host path. */
  readonly path: string
  /** Canonical Python `open()` mode, such as `'r'`, `'rb'`, or `'w'`. */
  readonly mode: string
  /** Current character or byte position. */
  readonly position: number

  /** Constructs a file handle to return from an `open` OS callback. */
  constructor(path: string, mode: string, options: MontyFileHandleOptions = {}) {
    if (typeof path !== 'string') throw new TypeError('MontyFileHandle path must be a string')
    if (typeof mode !== 'string') throw new TypeError('MontyFileHandle mode must be a string')
    const position = options.position ?? 0
    validateFilePosition(position)

    this.path = path
    this.mode = canonicalFileMode(mode)
    this.position = position
    Object.defineProperty(this, '__monty_type__', { value: 'FileHandle' })
    Object.freeze(this)
  }

  /** Whether the mode opens the file in binary form. */
  get binary(): boolean {
    return this.mode.includes('b')
  }

  /** Whether the mode permits reads. */
  get readable(): boolean {
    return this.mode.startsWith('r') || this.mode.includes('+')

View on GitHub (pinned to adc986b362)

Solutions

  1. Pass a valid mode string like 'r', 'w', 'a', 'rb'; check the argument order (path first, mode second).
  2. Default explicitly when the mode is optional: `mode ?? 'r'` only after confirming a string is intended.
  3. Validate with `typeof mode === 'string'` before constructing.

Example fix

// before
const handle = new MontyFileHandle(path); // mode undefined

// after
const handle = new MontyFileHandle(path, 'r');
Defensive patterns

Strategy: validation

Validate before calling

function assertMode(v) { if (typeof v !== 'string') throw new TypeError('mode must be a string'); return v; }
assertMode(mode);

Type guard

const isFileMode = (v: unknown): v is string => typeof v === 'string' && /^[rwaxb+t]*$/.test(v);

Try / catch

try {
  return new MontyFileHandle(path, mode);
} catch (e) {
  if (e instanceof TypeError && e.message === 'MontyFileHandle mode must be a string') {
    return new MontyFileHandle(path, 'r'); // safe default
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling `new MontyFileHandle(path, mode)` where mode is `undefined` (forgotten argument), a number, an options object, or a non-string constant from a config.

Common situations: Callback code omits the mode or swaps the argument order (`new MontyFileHandle(mode, path)`); or the mode is read from untyped env/config input.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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