jsdom/jsdom · error · TypeError
The options object may only set 'characterDataOldValue' to t
Error message
The options object may only set 'characterDataOldValue' to true when 'characterData' is true or not present.
What it means
`characterDataOldValue` requests old character-data values, which is only meaningful when character-data mutations are observed. jsdom throws this TypeError when `characterDataOldValue` is truthy but `characterData` is not explicitly true, per the MutationObserver spec's validation steps.
Source
Thrown at lib/jsdom/living/mutation-observer/MutationObserver-impl.js:47
if (("attributeOldValue" in options || "attributeFilter" in options) && !("attributes" in options)) {
options.attributes = true;
}
if ("characterDataOldValue" in options & !("characterData" in options)) {
options.characterData = true;
}
if (!options.childList && !options.attributes && !options.characterData) {
throw new TypeError("The options object must set at least one of 'attributes', 'characterData', or 'childList' " +
"to true.");
} else if (options.attributeOldValue && !options.attributes) {
throw new TypeError("The options object may only set 'attributeOldValue' to true when 'attributes' is true or " +
"not present.");
} else if (("attributeFilter" in options) && !options.attributes) {
throw new TypeError("The options object may only set 'attributeFilter' when 'attributes' is true or not " +
"present.");
} else if (options.characterDataOldValue && !options.characterData) {
throw new TypeError("The options object may only set 'characterDataOldValue' to true when 'characterData' is " +
"true or not present.");
}
const existingRegisteredObserver = target._registeredObserverList.find(registeredObserver => {
return registeredObserver.observer === this;
});
if (existingRegisteredObserver) {
for (const node of this._nodeList) {
node._registeredObserverList = node._registeredObserverList.filter(registeredObserver => {
return registeredObserver.source !== existingRegisteredObserver;
});
}
existingRegisteredObserver.options = options;
} else {
target._registeredObserverList.push({
observer: this,View on GitHub (pinned to 904cc9cd24)
Solutions
- Add `characterData: true` alongside `characterDataOldValue: true`.
- Derive it: `if (options.characterDataOldValue) options.characterData = true;` before observe().
- Remember `subtree: true` does not replace the characterData flag; set both.
- Remove characterDataOldValue if old values are not needed.
Example fix
// before
observer.observe(target, { subtree: true, characterDataOldValue: true }); // TypeError
// after
observer.observe(target, { subtree: true, characterData: true, characterDataOldValue: true }); Defensive patterns
Strategy: validation
Validate before calling
if (options.characterDataOldValue && options.characterData !== true) {
options.characterData = true;
} Type guard
function hasValidCharacterDataOptions(o) {
return !o.characterDataOldValue || o.characterData === true;
} Try / catch
try {
observer.observe(target, options);
} catch (e) {
if (e instanceof TypeError && /characterDataOldValue/.test(e.message)) {
observer.observe(target, { ...options, characterData: true });
} else {
throw e;
}
} Prevention
- Pair characterDataOldValue: true with characterData: true.
- Remember subtree: true does not enable characterData; set it explicitly.
- Validate observer options with a schema helper before calling observe().
When it happens
Trigger: `observer.observe(target, { characterDataOldValue: true })` without `characterData: true`; observing with `{ subtree: true, characterDataOldValue: true }` assuming subtree enables character data (it does not); merged options where characterData was lost.
Common situations: Believing subtree: true plus characterDataOldValue is sufficient; config templates listing characterDataOldValue but not characterData; refactors renaming characterData to textChanges.
Related errors
- The options object must set at least one of 'attributes', 'c
- The options object may only set 'attributeOldValue' to true
- The options object may only set 'attributeFilter' when 'attr
- Invalid Sequence
- Constructor argument is not a constructor.
AI-assisted analysis of jsdom/jsdom@904cc9cd24 (2026-09-01).
Data as JSON: /api/errors/31d85c922c2c991b.
Report an issue: GitHub.