{"record":{"id":"1a17109ef3061141","repo":"pydantic/monty","slug":"field-must-be-all-undefined-or-a-list-set-of-names-got","errorCode":null,"errorMessage":"${field} must be 'all', undefined or a list/Set of names, got '${policy}'","messagePattern":"(.+?) must be 'all', undefined or a list/Set of names, got '(.+?)'","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"crates/monty-js/ts/classInstance.ts","lineNumber":755,"sourceCode":"}\n\n/** Canonical 8-4-4-4-12 hex uuid; case-insensitive since `normalizeId` lowercases. */\nconst UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i\n\n/** Validates a caller-supplied wrapper id and lowercases it, so the id the\n *  sandbox reports back (always lowercase) is the key the store holds. */\nfunction normalizeId(wrapperKind: string, id: string): string {\n  if (typeof id !== 'string' || !UUID_PATTERN.test(id)) {\n    throw new TypeError(`${wrapperKind} id must be a canonical uuid string, got ${JSON.stringify(id)}`)\n  }\n  return id.toLowerCase()\n}\n\n/** Rejects a string policy other than `'all'`: a bare `'greet'` would\n *  otherwise be treated as a character array (`'g'`, `'r'`, ...). */\nfunction validatePolicy(field: string, policy: AttrPolicy | undefined): void {\n  if (typeof policy === 'string' && policy !== 'all') {\n    throw new TypeError(`${field} must be 'all', undefined or a list/Set of names, got '${policy}'`)\n  }\n}\n\n/** Names no policy may expose, `'all'` or explicit: JS object machinery\n *  that would hand the sandbox the class, its prototype, or a call stack. */\nconst DENIED_NAMES: ReadonlySet<string> = new Set(['constructor', '__proto__', 'prototype', 'arguments', 'caller'])\n\n/** Whether `policy` exposes `name`; `'all'` never exposes underscore names,\n *  and [`DENIED_NAMES`] are refused whichever form the policy takes. */\nfunction policyAllows(policy: AttrPolicy | undefined, name: string): boolean {\n  if (policy === undefined || DENIED_NAMES.has(name)) {\n    return false\n  }\n  if (policy === 'all') {\n    return !name.startsWith('_')\n  }\n  // Duck-type on `.has` rather than `instanceof Set` so set-likes from\n  // another realm (iframe / VM context) work too.","sourceCodeStart":737,"sourceCodeEnd":773,"githubUrl":"https://github.com/pydantic/monty/blob/adc986b362e3961f407868cb118a99fe831b9e61/crates/monty-js/ts/classInstance.ts#L737-L773","documentation":"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.","triggerScenarios":"Passing options like { attrs: 'greet' } or { attrsWrite: 'name,age' } when registering a class, instead of 'all', undefined, ['greet'], or new Set(['greet']).","commonSituations":"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.","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"],"exampleFix":"// before\nClassType(MyClass, { attrs: 'greet' });\n// after\nClassType(MyClass, { attrs: ['greet'] });","handlingStrategy":"validation","validationCode":"function assertPolicy(p) {\n  if (p !== undefined && p !== 'all' && !(Array.isArray(p) || p instanceof Set)) {\n    throw new Error(`policy must be 'all', undefined or a list/Set, got ${JSON.stringify(p)}`);\n  }\n}\nassertPolicy(opts.attrs);","typeGuard":"function isValidPolicy(p) {\n  return p === undefined || p === 'all' || Array.isArray(p) || p instanceof Set;\n}","tryCatchPattern":"try {\n  const type = ClassType(MyClass, { attrs: policy });\n} catch (e) {\n  if (e instanceof TypeError && e.message.includes(\"must be 'all', undefined or a list/Set\")) {\n    throw new Error(\"use 'all' or an array of names, e.g. ['greet']\");\n  }\n  throw e;\n}","preventionTips":["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"],"tags":["typescript","attribute-policy","configuration","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"adc986b362e3961f407868cb118a99fe831b9e61","analyzedAt":"2026-09-13T19:19:18.698Z","contentChangedAt":"2026-09-13T19:19:18.698Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}