dotnet/AspNetCore.Docs · error · Error

There already is an object with the key that you specified.

Error message

There already is an object with the key that you specified.

What it means

knockout.mapping augments mapped observableArrays with keyed helpers (mappedIndexOf, mappedCreate). mappedCreate enforces uniqueness: if mappedIndexOf(value) !== -1, an item with that key already exists and it throws rather than create a duplicate. The key is derived via the configured `key` callback.

Source

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

					var arrayOfKeys = filterArrayByKey(arrayOfValues, keyCallback);
					return mappedRootObject.destroy(function (item) {
						return ko.utils.arrayIndexOf(arrayOfKeys, keyCallback(item)) != -1;
					});
				}

				mappedRootObject.mappedIndexOf = function (item) {
					var keys = filterArrayByKey(mappedRootObject(), keyCallback);
					var key = keyCallback(item);
					return ko.utils.arrayIndexOf(keys, key);
				}

				mappedRootObject.mappedGet = function (item) {
					return mappedRootObject()[mappedRootObject.mappedIndexOf(item)];
				}

				mappedRootObject.mappedCreate = function (value) {
					if (mappedRootObject.mappedIndexOf(value) !== -1) {
						throw new Error("There already is an object with the key that you specified.");
					}

					var item = hasCreateCallback() ? createCallback(value) : value;
					if (hasUpdateCallback()) {
						var newValue = updateCallback(item, value);
						if (ko.isWriteableObservable(item)) {
							item(newValue);
						} else {
							item = newValue;
						}
					}
					mappedRootObject.push(item);
					return item;
				}
			}

			var currentArrayKeys = filterArrayByKey(ko.utils.unwrapObservable(mappedRootObject), keyCallback).sort();
			var newArrayKeys = filterArrayByKey(rootObject, keyCallback);

View on GitHub (pinned to c67a80103a)

Solutions

  1. Check before creating: if (viewModel.mappedIndexOf(newItem) === -1) viewModel.mappedCreate(newItem);
  2. Ensure the `key` callback produces unique keys for distinct items.
  3. Dedupe incoming server data before mapping.
  4. If duplicates are legitimate, switch to viewModel.push() instead of mappedCreate.

Example fix

// before
viewModel.mappedCreate(newItem); // throws if key exists
// after
if (viewModel.mappedIndexOf(newItem) === -1) {
  viewModel.mappedCreate(newItem);
}
Defensive patterns

Strategy: validation

Validate before calling

// Dedupe before mappedCreate.
function safeMappedCreate(arr, value) {
  if (arr.mappedIndexOf(value) !== -1) {
    console.warn('Duplicate key; skipping mappedCreate', value);
    return;
  }
  return arr.mappedCreate(value);
}

Type guard

function hasUniqueKey(arr, value) { return arr.mappedIndexOf(value) === -1; }

Try / catch

try {
  viewModel.mappedCreate(newItem);
} catch (e) {
  if (/already is an object with the key/.test(e.message)) {
    console.warn('Item already present; updating instead');
    var idx = viewModel.mappedIndexOf(newItem);
    if (idx !== -1) viewModel()[idx](newItem);
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling viewModel.mappedCreate(newItem) when an item with the same key already exists in the array; server pushing a duplicate id; key callback returning a colliding value.

Common situations: REST endpoints returning the same record twice; optimistic UI creating then receiving a server echo; key function ignoring a sub-field so distinct items collide.

Related errors


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