{"record":{"id":"ff407a1345b84b00","repo":"danny-avila/LibreChat","slug":"path-key-must-be-an-enumerable-property","errorCode":null,"errorMessage":"${path}.${key} must be an enumerable property","messagePattern":"(.+?)\\.(.+?) must be an enumerable property","errorType":"validation","errorClass":"AgentRunEnvelopeError","httpStatus":null,"severity":"error","filePath":"packages/api/src/agents/envelope.ts","lineNumber":174,"sourceCode":"        clonedItemCount++;\n      }\n      if (clonedItemCount !== value.length) {\n        throw new AgentRunEnvelopeError(`${path} contains sparse array entries`);\n      }\n      return cloned;\n    }\n\n    const prototype = Object.getPrototypeOf(value);\n    if (prototype !== Object.prototype && prototype !== null) {\n      const typeName = value.constructor?.name ?? 'object';\n      throw new AgentRunEnvelopeError(`${path} contains a non-plain ${typeName} value`);\n    }\n\n    const cloned: { [key: string]: unknown } = {};\n    for (const key of Object.getOwnPropertyNames(value)) {\n      const descriptor = Object.getOwnPropertyDescriptor(value, key);\n      if (descriptor?.enumerable !== true) {\n        throw new AgentRunEnvelopeError(`${path}.${key} must be an enumerable property`);\n      }\n      if (!Object.prototype.hasOwnProperty.call(descriptor, 'value')) {\n        throw new AgentRunEnvelopeError(`${path}.${key} must not be an accessor property`);\n      }\n      const propertyValue: unknown = descriptor.value;\n      Object.defineProperty(cloned, key, {\n        configurable: true,\n        enumerable: true,\n        writable: true,\n        value: cloneJsonValue(propertyValue, `${path}.${key}`, ancestors, depth + 1),\n      });\n    }\n    return cloned;\n  } finally {\n    ancestors.delete(value);\n  }\n}\n","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/danny-avila/LibreChat/blob/5ff282f9006c436e561de1afd39a481bea1ef0d8/packages/api/src/agents/envelope.ts#L156-L192","documentation":"Thrown by cloneJsonValue when a plain object's own property descriptor has enumerable !== true. Object.getOwnPropertyNames returns non-enumerable keys too, so properties defined with enumerable:false (or hidden flags) are caught. JSON.stringify skips non-enumerable keys, which would silently drop data; the envelope clone surfaces the loss as an error.","triggerScenarios":"Object.defineProperty(obj, 'id', { value: 1, enumerable: false }), or libraries that define config fields as non-enumerable. Also class fields declared as non-enumerable via decorators.","commonSituations":"Using defineProperty for 'private' fields that you later need in the payload; objects returned from Object.assign over a frozen/non-enumerable template; ORM hidden columns flagged non-enumerable.","solutions":["Recreate the object as a literal containing only the fields you need, copied by name.","Redefine the property as enumerable: Object.defineProperty(obj, key, { enumerable: true }).","Use Object.entries / a manual pick list (which only see enumerable props) to rebuild a clean plain object."],"exampleFix":"// before\nObject.defineProperty(cfg, 'secret', { value: 'x', enumerable: false });\ncreateAgentRunEnvelope({ protocol, requestId, receivedAt, principal, payload: { cfg } });\n\n// after\nconst cfg = { ...{ secret: 'x' } }; // literal, enumerable by default\ncreateAgentRunEnvelope({ protocol, requestId, receivedAt, principal, payload: { cfg } });","handlingStrategy":"validation","validationCode":"function allOwnPropsEnumerable(obj: Record<string, unknown>): boolean {\n  return Object.getOwnPropertyNames(obj).every((k) =>\n    Object.getOwnPropertyDescriptor(obj, k)?.enumerable === true);\n}\nfunction toEnumerablePlain<T extends Record<string, unknown>>(obj: T): Record<string, unknown> {\n  const out: Record<string, unknown> = {};\n  for (const [k, v] of Object.entries(obj)) out[k] = v; // entries sees only enumerable\n  return out;\n}","typeGuard":"function isAllEnumerable(obj: Record<PropertyKey, unknown>): boolean {\n  return Object.getOwnPropertyNames(obj).every(\n    (k) => Object.getOwnPropertyDescriptor(obj, k)?.enumerable === true,\n  );\n}","tryCatchPattern":"try {\n  const env = createAgentRunEnvelope(input);\n} catch (e) {\n  if (e instanceof AgentRunEnvelopeError && /enumerable property/.test(e.message)) {\n    input.payload = JSON.parse(JSON.stringify(input.payload)) as typeof input.payload;\n    // JSON round-trip drops non-enumerable keys; confirm that is acceptable\n  } else throw e;\n}","preventionTips":["Avoid Object.defineProperty with enumerable:false on payload-bound objects.","Build payload objects as literals; do not reuse frozen/hidden-flag templates.","Test that Object.keys(payload) returns every field you intend to send."],"tags":["serialization","json","enumerable","define-property","agent-envelope"],"backgroundTag":null,"analyzedSha":"5ff282f9006c436e561de1afd39a481bea1ef0d8","analyzedAt":"2026-08-12T21:38:08.145Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}