pydantic/monty · error · TypeError

Monty${typeName} timezoneName requires offsetSeconds

Error message

Monty${typeName} timezoneName requires offsetSeconds

What it means

timeZoneFields validates marker objects for DateTime/Time values: a timezone name may only appear together with an offsetSeconds (i.e. the value must be tz-aware). A timezoneName without offsetSeconds is considered an orphaned/malformed marker and rejected with this TypeError.

Source

Thrown at crates/monty-js/ts/worker/value.ts:160

      if (typeof object.classType === 'object' && object.classType !== null) {
        return { tag: 'class-type', val: pushClassType(object.classType as Record<string, unknown>, nodes) }
      }
      return { tag: 'type-name', val: String(object.value) }
    case 'BuiltinFunction':
      return { tag: 'builtin-function', val: String(object.value) }
    default:
      throw new TypeError(`Unknown Monty marker type: ${String(object[TYPE_MARKER])}`)
  }
}

/** Preserves aware-time metadata while rejecting an orphaned timezone name. */
function timeZoneFields(
  object: Record<string, unknown>,
  typeName: 'DateTime' | 'Time',
): { offsetSeconds?: number; timezoneName?: string } {
  const aware = object.offsetSeconds !== undefined && object.offsetSeconds !== null
  if (!aware && object.timezoneName !== undefined && object.timezoneName !== null) {
    throw new TypeError(`Monty${typeName} timezoneName requires offsetSeconds`)
  }
  return aware
    ? {
        offsetSeconds: Number(object.offsetSeconds),
        ...(typeof object.timezoneName === 'string' ? { timezoneName: object.timezoneName } : {}),
      }
    : {}
}

/**
 * Validates and converts a host `ClassInstance` marker (same shape the napi
 * path produces: `attrs` as ordered `[name, value]` pairs, uuids as
 * strings). Validation messages mirror napi's so both transports fail
 * malformed markers alike.
 */
function pushClassInstance(object: Record<string, unknown>, nodes: ValueNode[]): ValueNode {
  if (typeof object.type !== 'object' || object.type === null) {
    throw new TypeError(

View on GitHub (pinned to adc986b362)

Solutions

  1. Include a numeric offsetSeconds whenever timezoneName is set
  2. If the time is naive, remove timezoneName entirely instead of sending it without an offset
  3. Check any JSON serialization step so undefined offsetSeconds does not silently drop the pairing field

Example fix

// before
{ marker: 'DateTime', year: 2026, month: 9, day: 13, timezoneName: 'Europe/Berlin' }
// after
{ marker: 'DateTime', year: 2026, month: 9, day: 13, offsetSeconds: 7200, timezoneName: 'Europe/Berlin' }
Defensive patterns

Strategy: validation

Validate before calling

function validateTimeFields(o: Record<string, unknown>): void {
  const aware = o.offsetSeconds !== undefined && o.offsetSeconds !== null
  if (!aware && o.timezoneName != null) throw new Error('timezoneName requires offsetSeconds')
}

Type guard

const isConsistentTime = (o: Record<string, unknown>): boolean =>
  !((o.offsetSeconds === undefined || o.offsetSeconds === null) && o.timezoneName != null)

Try / catch

try {
  await session.feedRun(code, { inputs: { when: dateTimeMarker } })
} catch (e) {
  if (e instanceof TypeError && e.message.includes('timezoneName requires offsetSeconds')) {
    // repair or drop the timezone name, then retry
  }
  throw e
}

Prevention

When it happens

Trigger: Supplying a MontyDateTime or MontyTime marker object where offsetSeconds is undefined/null but timezoneName is a non-empty string — e.g. hand-constructing an aware datetime input, or dropping the offsetSeconds field while keeping timezoneName when mapping values between systems.

Common situations: Building datetime inputs for a monty session by hand and forgetting offsetSeconds; a custom serializer that omits undefined fields (e.g. JSON round-trip dropping undefined) leaving timezoneName behind; naive/aware confusion when bridging host date objects.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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