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
- Check before creating: if (viewModel.mappedIndexOf(newItem) === -1) viewModel.mappedCreate(newItem);
- Ensure the `key` callback produces unique keys for distinct items.
- Dedupe incoming server data before mapping.
- 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
- Always call mappedIndexOf before mappedCreate.
- Ensure the `key` callback yields unique, stable keys.
- Dedupe server payloads before mapping them into the array.
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
- When calling ko.fromJS, pass the object you want to convert.
- ko.mapping.updateFromJS, use ko.mapping.fromJS instead. Plea
- ko.mapping.updateFromJSON, use ko.mapping.fromJSON instead.
- When calling ko.mapping.toJS, pass the object you want to co
- ko.mapping.defaultOptions().ignore should be an array.
AI-assisted analysis of dotnet/AspNetCore.Docs@c67a80103a (2026-08-13).
Data as JSON: /api/errors/8a7a30dd4714a316.
Report an issue: GitHub.