dotnet/AspNetCore.Docs · error · Error
When calling ko.update*, the key '${key}' was not found!
Error message
When calling ko.update*, the key '${key}' was not found! What it means
knockout.mapping's internal getItemByKey walks the array comparing mapKey(item, callback) to the requested key; if no element matches it throws. This fires during update operations when the new data references a key that isn't currently in the mapped array — typically because the client's data is stale or the key callback is inconsistent.
Source
Thrown at aspnetcore/mvc/controllers/testing/samples/2.x/TestingControllersSample/src/TestingControllersSample/wwwroot/js/knockout.mapping.js:659
return null;
}
function mapKey(item, callback) {
var mappedItem;
if (callback) mappedItem = callback(item);
if (exports.getType(mappedItem) === "undefined") mappedItem = item;
return ko.utils.unwrapObservable(mappedItem);
}
function getItemByKey(array, key, callback) {
array = ko.utils.unwrapObservable(array);
for (var i = 0, j = array.length; i < j; i++) {
var item = array[i];
if (mapKey(item, callback) === key) return item;
}
throw new Error("When calling ko.update*, the key '" + key + "' was not found!");
}
function filterArrayByKey(array, callback) {
return ko.utils.arrayMap(ko.utils.unwrapObservable(array), function (item) {
if (callback) {
return mapKey(item, callback);
} else {
return item;
}
});
}
function visitPropertiesOrArrayEntries(rootObject, visitorCallback) {
if (exports.getType(rootObject) === "array") {
for (var i = 0; i < rootObject.length; i++)
visitorCallback(i);
} else {
for (var propertyName in rootObject)View on GitHub (pinned to c67a80103a)
Solutions
- Refresh the underlying data fully so keys line up before updating.
- Verify the `key` callback reads a stable, unique field.
- Handle the missing case gracefully by reloading from server rather than updating in place.
Example fix
// before // partial update referencing a key not present -> throws ko.mapping.fromJS(partialData, viewModel); // after - full refresh first ko.mapping.fromJS(fullData, viewModel);
Defensive patterns
Strategy: validation
Validate before calling
// Verify a key exists before any update path that looks it up.
function keyExists(arr, key, keyCallback) {
return ko.utils.unwrapObservable(arr).some(function (item) {
return keyCallback(item) === key;
});
}
if (!keyExists(viewModel, targetKey, keyCb)) {
console.warn('Key not present; refreshing from server instead of updating');
return refresh();
} Type guard
function itemHasKey(arr, key, keyCallback) {
return ko.utils.unwrapObservable(arr).some(function (i) { return keyCallback(i) === key; });
} Try / catch
try {
ko.mapping.fromJS(delta, viewModel);
} catch (e) {
if (/key .* was not found/.test(e.message)) {
console.warn('Stale view-model; doing full reload');
return reloadAll();
}
throw e;
} Prevention
- Refresh the full collection before partial updates when keys may have drifted.
- Keep the `key` callback deterministic and stable across runs.
- Reconcile server/client data before invoking update paths.
When it happens
Trigger: Calling a ko.update*/mappedUpdate path with data whose key is absent from the existing array; key callback returning different values for the same logical item before vs after; concurrent server edits removing the item.
Common situations: Stale client view-model; partial refresh that omits an item another part references; key extracted from different fields over time.
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/729cdaeeb362e635.
Report an issue: GitHub.