hcengineering/platform · error · PlatformError
core.status.ObjectNotFound
core.status.ObjectNotFound
Error message
ObjectNotFound
What it means
setObjectValue builds nested intermediate objects when applying a dotted-path update. When the path traverses an array (dots present) it cannot safely create nested values inside arrays, so it throws a PlatformError with core.status.ObjectNotFound and _id:'dots' to signal 'arrays are not supported' for this update path.
Source
Thrown at foundations/core/packages/core/src/objvalue.ts:53
*/
export function setObjectValue (key: string, doc: Doc, newValue: any): void {
// Check dot notation
if (key.length === 0) {
return
}
key = key.split('\\$').join('$')
let dots = key.split('.')
// Replace escapting, since memdb is not escape keys
const last = dots[dots.length - 1]
dots = dots.slice(0, -1)
// We have dots, so iterate in depth
let value = doc as any
for (const d of dots) {
if (Array.isArray(value) && isNestedArrayQuery(value, d)) {
// Arrays are not supported
throw new PlatformError(new Status(Severity.ERROR, core.status.ObjectNotFound, { _id: 'dots' }))
}
const lvalue = value?.[d]
if (lvalue === undefined) {
value[d] = {}
value = value?.[d]
} else {
value = lvalue
}
}
value[last] = clone(newValue)
return value
}
function isNestedArrayQuery (value: any, d: string): boolean {
return Number.isNaN(Number.parseInt(d)) && value?.[d as any] === undefined
}
function getNestedArrayValue (value: any[], name: string): any[] {View on GitHub (pinned to 63e28dc964)
Solutions
- Restructure the update to replace the whole array field instead of addressing elements by dotted path
- Load the doc, mutate the array in code, and update via a non-dotted patch
- Change the data model so the nested collection is a separate AttachedDoc rather than an embedded array
- Catch this status code and surface a clear 'array updates not supported' message
Example fix
// before
await applyUpdate(doc._id, doc._class, { 'items.0.done': true })
// after
const items = (doc.items ?? []).map((it, i) => i === 0 ? { ...it, done: true } : it)
await applyUpdate(doc._id, doc._class, { items }) Defensive patterns
Strategy: validation
Validate before calling
const key = 'items.0.done'
const root = key.split('.')[0]
const probe = (doc as any)[root]
if (Array.isArray(probe)) {
throw new Error(`Dotted update '${key}' targets an array; replace the whole field instead`)
}
await applyUpdate(doc._id, doc._class, { [key]: value }) Try / catch
try {
await applyUpdate(_id, _class, patch)
} catch (err: any) {
if (err?.status?.code === core.status.ObjectNotFound && err?.status?.params?._id === 'dots') {
// array update rejected - fallback to whole-field replacement
return applyWholeFieldUpdate(_id, _class, patch)
}
throw err
} Prevention
- Avoid dotted paths that traverse arrays; update the array field wholesale
- Model nested collections as AttachedDoc relations instead of embedded arrays
- Sanitize incoming patch keys against the class attribute types
- Test update paths against real document shapes in CI
When it happens
Trigger: Calling setObjectValue (via applyUpdate or updateMixin4Doc) with a patch key containing dots that resolves into an array element, e.g. 'items.0.name' or 'tags.x' where tags is an array and isNestedArrayQuery matches.
Common situations: UI forms generating dotted paths over array fields; migrating updates written for a plain object schema while the attribute was changed to an array; mixin updates addressing array-of-objects properties.
Related errors
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/4ba719c6426761d3.
Report an issue: GitHub.