dotnet/AspNetCore.Docs · error · Error

ko.mapping.defaultOptions().include should be an array.

Error message

ko.mapping.defaultOptions().include should be an array.

What it means

knockout.mapping.js validates `defaultOptions().include` is an array. include lists properties that mapping should process even when they are not normally mapped (e.g. computed observables); a non-array breaks the merge logic.

Source

Thrown at aspnetcore/mvc/controllers/testing/samples/3.x/TestingControllersSample/src/TestingControllersSample/wwwroot/js/knockout.mapping.js:156

		var parsed = ko.utils.parseJson(jsonString);
		arguments[0] = parsed;
		return exports.fromJS.apply(this, arguments);
	};

	exports.updateFromJS = function (viewModel) {
		throw new Error("ko.mapping.updateFromJS, use ko.mapping.fromJS instead. Please note that the order of parameters is different!");
	};

	exports.updateFromJSON = function (viewModel) {
		throw new Error("ko.mapping.updateFromJSON, use ko.mapping.fromJSON instead. Please note that the order of parameters is different!");
	};

	exports.toJS = function (rootObject, options) {
		if (!defaultOptions) exports.resetDefaultOptions();

		if (arguments.length == 0) throw new Error("When calling ko.mapping.toJS, pass the object you want to convert.");
		if (exports.getType(defaultOptions.ignore) !== "array") throw new Error("ko.mapping.defaultOptions().ignore should be an array.");
		if (exports.getType(defaultOptions.include) !== "array") throw new Error("ko.mapping.defaultOptions().include should be an array.");
		if (exports.getType(defaultOptions.copy) !== "array") throw new Error("ko.mapping.defaultOptions().copy should be an array.");

		// Merge in the options used in fromJS
		options = fillOptions(options, rootObject[mappingProperty]);

		// We just unwrap everything at every level in the object graph
		return exports.visitModel(rootObject, function (x) {
			return ko.utils.unwrapObservable(x)
		}, options);
	};

	exports.toJSON = function (rootObject, options) {
		var plainJavaScriptObject = exports.toJS(rootObject, options);
		return ko.utils.stringifyJson(plainJavaScriptObject);
	};

	exports.defaultOptions = function () {
		if (arguments.length > 0) {

View on GitHub (pinned to c67a80103a)

Solutions

  1. Set include as an array of property names: `ko.mapping.defaults.include = ["fullName"];`.
  2. Call `ko.mapping.resetDefaultOptions()` to clear the bad state.
  3. Centralize option setup in one bootstrap module so include/ignore/copy stay arrays.

Example fix

// before
ko.mapping.defaults.include = "computedField";

// after
ko.mapping.defaults.include = ["computedField"];
Defensive patterns

Strategy: validation

Validate before calling

function setInclude(props) {
  if (!Array.isArray(props)) throw new TypeError('include must be an array');
  ko.mapping.defaults.include = props;
}

Type guard

function isValidOptionArray(v) {
  return Array.isArray(v) && v.every(x => typeof x === 'string');
}

Try / catch

// Validate options at app start rather than catching per call:
['ignore','include','copy'].forEach(k => {
  if (!Array.isArray(ko.mapping.defaults[k])) ko.mapping.resetDefaultOptions();
});

Prevention

When it happens

Trigger: Assigning `defaultOptions().include` to a non-array (string, number, object) and then invoking any mapping operation that consults defaultOptions.

Common situations: Writing `include: "fullName"` instead of an array; bad merge of partial option objects; stale config from an older API version that accepted other shapes.

Related errors


AI-assisted analysis of dotnet/AspNetCore.Docs@c67a80103a (2026-08-13). Data as JSON: /api/errors/ffb2b20b905e6126. Report an issue: GitHub.