overleaf/overleaf · error
Referenced element not a number
Error message
Referenced element not a number
What it means
For 'na' (number add) components, the json type verifies the target element is of type number before applying the increment. If the value at elem[key] is a string, null, boolean, or undefined, applying would silently corrupt the document, so it throws instead.
Source
Thrown at services/document-updater/app/js/sharejs/types/json.js:110
let parentkey = null
let elem = container
let key = 'data'
for (const p of Array.from(c.p)) {
parent = elem
parentkey = key
elem = elem[key]
key = p
if (parent == null) {
throw new Error('Path invalid')
}
}
if (c.na !== undefined) {
// Number add
if (typeof elem[key] !== 'number') {
throw new Error('Referenced element not a number')
}
elem[key] += c.na
} else if (c.si !== undefined) {
// String insert
if (typeof elem !== 'string') {
throw new Error(
`Referenced element not a string (it was ${JSON.stringify(elem)})`
)
}
parent[parentkey] = elem.slice(0, key) + c.si + elem.slice(key)
} else if (c.sd !== undefined) {
// String delete
if (typeof elem !== 'string') {
throw new Error('Referenced element not a string')
}
if (elem.slice(key, key + c.sd.length) !== c.sd) {
throw new Error('Deleted string does not match')
}View on GitHub (pinned to 28ad3b03b7)
Solutions
- Initialize numeric fields to 0 before any na op runs
- Coerce or fix the field to a number first (submit an oi op setting a number), then use na
- Validate client-side that snapshot value at the path is typeof 'number' before submitting na
- Ensure all writers treat the field strictly as a number
Example fix
// before doc.at(['views']).increment(1) // views === null // after if (typeof doc.get().views !== 'number') doc.at(['views']).set(0) doc.at(['views']).increment(1)
Defensive patterns
Strategy: type-guard
Validate before calling
const v = doc.get().views // resolve path to target
if (typeof v !== 'number') throw new Error(`views is not a number: ${typeof v}`) Type guard
const isNumber = (v) => typeof v === 'number' && !Number.isNaN(v)
Try / catch
try {
doc.at(['views']).increment(1)
} catch (err) {
if (err.message === 'Referenced element not a number') {
doc.at(['views']).set(0)
doc.at(['views']).increment(1)
return
}
throw err
} Prevention
- Initialize numeric fields to 0 before any na ops
- Never initialize counters from raw string input; coerce with Number() first
- Check typeof === 'number' before submitting na ops
- Restrict writers of the field to code paths that preserve numeric type
When it happens
Trigger: Submitting na against a field holding a non-number — e.g. counter initialized to null or '0' (string), or the field was never created so it is undefined; another client replaced the counter with a string.
Common situations: Counters initialized from user/config input as strings; missing field on first use (undefined); a migration that changed the counter to a different type.
Related errors
- Referenced element not a list
- Referenced element not an object (it was ${JSON.stringify(el
- Referenced element not a string (it was ${JSON.stringify(ele
- sharejs-text-ot
- bad path
AI-assisted analysis of overleaf/overleaf@28ad3b03b7 (2026-09-03).
Data as JSON: /api/errors/45c8bb71cd89ac27.
Report an issue: GitHub.