pydantic/monty · error · TypeError
${field} must be 'all', undefined or a list/Set of names, go
Error message
${field} must be 'all', undefined or a list/Set of names, got '${policy}' What it means
Attribute exposure policies (e.g. attrs/read or write policy options) accept 'all', undefined, or a list/Set of attribute names. A bare string other than 'all' is rejected because it would otherwise be silently treated as a character array ('greet' -> 'g','r','e','e','t'). validatePolicy throws this TypeError naming the field and offending value.
Source
Thrown at crates/monty-js/ts/classInstance.ts:755
}
/** Canonical 8-4-4-4-12 hex uuid; case-insensitive since `normalizeId` lowercases. */
const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
/** Validates a caller-supplied wrapper id and lowercases it, so the id the
* sandbox reports back (always lowercase) is the key the store holds. */
function normalizeId(wrapperKind: string, id: string): string {
if (typeof id !== 'string' || !UUID_PATTERN.test(id)) {
throw new TypeError(`${wrapperKind} id must be a canonical uuid string, got ${JSON.stringify(id)}`)
}
return id.toLowerCase()
}
/** Rejects a string policy other than `'all'`: a bare `'greet'` would
* otherwise be treated as a character array (`'g'`, `'r'`, ...). */
function validatePolicy(field: string, policy: AttrPolicy | undefined): void {
if (typeof policy === 'string' && policy !== 'all') {
throw new TypeError(`${field} must be 'all', undefined or a list/Set of names, got '${policy}'`)
}
}
/** Names no policy may expose, `'all'` or explicit: JS object machinery
* that would hand the sandbox the class, its prototype, or a call stack. */
const DENIED_NAMES: ReadonlySet<string> = new Set(['constructor', '__proto__', 'prototype', 'arguments', 'caller'])
/** Whether `policy` exposes `name`; `'all'` never exposes underscore names,
* and [`DENIED_NAMES`] are refused whichever form the policy takes. */
function policyAllows(policy: AttrPolicy | undefined, name: string): boolean {
if (policy === undefined || DENIED_NAMES.has(name)) {
return false
}
if (policy === 'all') {
return !name.startsWith('_')
}
// Duck-type on `.has` rather than `instanceof Set` so set-likes from
// another realm (iframe / VM context) work too.View on GitHub (pinned to adc986b362)
Solutions
- Wrap names in an array: { attrs: ['greet'] }
- Use the literal 'all' if every attribute should be exposed
- If the value comes from config, coerce it: typeof p === 'string' && p !== 'all' ? p.split(',') : p
Example fix
// before
ClassType(MyClass, { attrs: 'greet' });
// after
ClassType(MyClass, { attrs: ['greet'] }); Defensive patterns
Strategy: validation
Validate before calling
function assertPolicy(p) {
if (p !== undefined && p !== 'all' && !(Array.isArray(p) || p instanceof Set)) {
throw new Error(`policy must be 'all', undefined or a list/Set, got ${JSON.stringify(p)}`);
}
}
assertPolicy(opts.attrs); Type guard
function isValidPolicy(p) {
return p === undefined || p === 'all' || Array.isArray(p) || p instanceof Set;
} Try / catch
try {
const type = ClassType(MyClass, { attrs: policy });
} catch (e) {
if (e instanceof TypeError && e.message.includes("must be 'all', undefined or a list/Set")) {
throw new Error("use 'all' or an array of names, e.g. ['greet']");
}
throw e;
} Prevention
- Never pass bare strings other than 'all' as attr policies
- Coerce comma-separated config values with .split(',') before passing
- Type policies as `'all' | string[] | Set<string> | undefined` in your own code
When it happens
Trigger: Passing options like { attrs: 'greet' } or { attrsWrite: 'name,age' } when registering a class, instead of 'all', undefined, ['greet'], or new Set(['greet']).
Common situations: Comma-separated string lists copied from config files; a single method name passed as a string assuming string-or-array support; dynamically built policies that degrade to strings.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- classType does not match the instance's class
- pass name on the ClassType wrapper, not alongside classType
- Max input depth exceeded
- ClassInstance marker instanceId must be a uuid string
- invalid mount mode: '${mode}'. Expected 'read-only', 'read-w
AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13).
Data as JSON: /api/errors/1a17109ef3061141.
Report an issue: GitHub.