{"record":{"id":"1a60a5d037684188","repo":"danny-avila/LibreChat","slug":"path-key-must-not-be-an-accessor-property","errorCode":null,"errorMessage":"${path}.${key} must not be an accessor property","messagePattern":"(.+?)\\.(.+?) must not be an accessor property","errorType":"validation","errorClass":"AgentRunEnvelopeError","httpStatus":null,"severity":"error","filePath":"packages/api/src/agents/envelope.ts","lineNumber":177,"sourceCode":"        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\nfunction createPrincipal(input: AgentRunPrincipalInput | null | undefined): AgentRunPrincipal {\n  const userId = assertNonEmptyString(input?.id, 'principal.id');\n  const principal: AgentRunPrincipal = { userId };","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/danny-avila/LibreChat/blob/5ff282f9006c436e561de1afd39a481bea1ef0d8/packages/api/src/agents/envelope.ts#L159-L195","documentation":"Thrown by cloneJsonValue when a plain object's own enumerable property is an accessor (defined with get/set) rather than a data value. The descriptor lacks an own 'value' key. Getters can throw or have side effects, so the clone refuses to invoke them and demands a concrete value.","triggerScenarios":"Object.defineProperty(obj, 'k', { get() {...}, enumerable: true }), a class instance turned plain-ish via assignment but still carrying getters, or a Proxy whose trap surfaces as an accessor descriptor.","commonSituations":"Computed/derived fields exposed as getters on a config object; interop with libraries that expose lazy properties; spreading a class instance into a plain object while getters survive.","solutions":["Evaluate getters into plain values: build { k: obj.k } by reading each field explicitly.","Replace accessor descriptors with data descriptors (defineProperty with value).","Use Object.entries(obj) to harvest concrete values into a fresh literal."],"exampleFix":"// before\nObject.defineProperty(meta, 'summary', { get() { return title + ' - ' + body; }, enumerable: true });\ncreateAgentRunEnvelope({ protocol, requestId, receivedAt, principal, payload: { meta } });\n\n// after\nconst meta = { summary: title + ' - ' + body };\ncreateAgentRunEnvelope({ protocol, requestId, receivedAt, principal, payload: { meta } });","handlingStrategy":"validation","validationCode":"function objectHasOnlyDataValues(obj: Record<string, unknown>): boolean {\n  return Object.getOwnPropertyNames(obj).every((k) => {\n    const d = Object.getOwnPropertyDescriptor(obj, k);\n    return !!d && Object.prototype.hasOwnProperty.call(d, 'value');\n  });\n}\nfunction materializeGetters<T extends Record<string, unknown>>(obj: T): Record<string, unknown> {\n  const out: Record<string, unknown> = {};\n  for (const k of Object.keys(obj)) out[k] = obj[k]; // invoke getter, store value\n  return out;\n}","typeGuard":"function isDataPropsOnly(obj: Record<PropertyKey, unknown>): boolean {\n  return Object.getOwnPropertyNames(obj).every((k) => {\n    const d = Object.getOwnPropertyDescriptor(obj, k);\n    return !!d && Object.prototype.hasOwnProperty.call(d, 'value');\n  });\n}","tryCatchPattern":"try {\n  const env = createAgentRunEnvelope(input);\n} catch (e) {\n  if (e instanceof AgentRunEnvelopeError && /accessor property/.test(e.message)) {\n    input.payload = JSON.parse(JSON.stringify(input.payload)) as typeof input.payload;\n    // getters are invoked and results stored as plain values\n  } else throw e;\n}","preventionTips":["Do not define getters on payload objects; compute values up front into plain fields.","Run a JSON round-trip in tests to confirm no accessors survive into the envelope.","Build payloads from explicit field assignment rather than class instances with getters."],"tags":["serialization","json","accessor-property","define-property","agent-envelope"],"backgroundTag":null,"analyzedSha":"5ff282f9006c436e561de1afd39a481bea1ef0d8","analyzedAt":"2026-08-12T21:38:08.145Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}