Knockout JS Error: Cannot write a value to a ko.computed unless you specify a 'write' option
<p>Having an issue that isn't necessarily game breaking. I have a simple table with sort, and 2 filters. One filter populated by array (active, inactive, show all) and one based on search criteria. </p>

<p>The code works. But when I have developer tools up I get the following error: </p>

<blockquote>
  <p>Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.</p>
</blockquote>

<p>My code is below, and I set up a JS Fiddle but I can't get it work, so I'm not sure it's helpful - <a href="https://jsfiddle.net/cliffchambers/rbmp2rtk/9/" rel="nofollow">Fiddle</a></p>

<p><div class="snippet" data-lang="js" data-hide="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>var sgsoip = window.sgsoip || {};
sgsoip.FunctionalArea = function (FunctionalAreaID, FunctionalAreaName, FunctionalAreaActive) {
    'use strict';
    this.FunctionalAreaID = ko.observable(FunctionalAreaID);
    this.FunctionalAreaName = ko.observable(FunctionalAreaName);//.extend({ required: "Functional Area Name is required" });
    this.FunctionalAreaActive = ko.observable(FunctionalAreaActive);//.extend({ required: "Active is required" });
    //this.HasError = ko.pureComputed(function () {
    //    return this.FunctionalAreaActive.hasError() || this.FunctionalAreaName.hasError();
    //}, this);
};

var sgsoip = window.sgsoip || {};
sgsoip.FunctionalAreaViewModel = function (ko) {
    var self = this;
    self.functionalAreas = ko.observableArray([]);
    self.search = ko.observable('');

    
    self.headers = [
        { title: '', sortPropertyName: '', asc: true, active: false },
        { title: 'Functional Area Name', sortPropertyName: 'FunctionalAreaName', asc: true, active: true },
        { title: 'Active', sortPropertyName: 'FunctionalAreaActive', asc: true, active: false }
    ];
    self.filters = [
        { title: "Show All", filter: null },
        { title: "Active", filter: function (item) { return item.FunctionalAreaActive() === true; } },
        { title: "Inactive", filter: function (item) { return item.FunctionalAreaActive() === false; } }
    ];

    self.activeFilter = ko.observable(self.filters[0].filter);
    self.activeSort = ko.observable(function () { return 1; }); //set the default sort

    self.setActiveFilter = function (model, event) {
        self.activeFilter(model.filter);
    }
    
    self.sort = function (header, event) {
        //if this header was just clicked a second time
        if (header.active) {
            header.asc = !header.asc; //toggle the direction of the sort
        }
        //make sure all other headers are set to inactive
        ko.utils.arrayForEach(self.headers, function (item) { item.active = false; });
        //the header that was just clicked is now active
        header.active = true;//our now-active header

        var prop = header.sortPropertyName;
        var ascSort = function (a, b) { return a[prop]() &lt; b[prop]() ? -1 : a[prop]() &gt; b[prop]() ? 1 : a[prop]() == b[prop]() ? 0 : 0; };
        var descSort = function (a, b) { return a[prop]() &gt; b[prop]() ? -1 : a[prop]() &lt; b[prop]() ? 1 : a[prop]() == b[prop]() ? 0 : 0; };
        var sortFunc = header.asc ? ascSort : descSort;

        //store the new active sort function
        self.activeSort(sortFunc);
    };


    self.filteredItems = ko.computed(function () {
        var result;
        if (self.activeFilter()) {
            result = ko.utils.arrayFilter(self.functionalAreas(), self.activeFilter());
        } else {
            result = self.functionalAreas();
        }

        if (self.search()) {
            return (ko.utils.arrayFilter(result, function (item) {
                return item.FunctionalAreaName().toLowerCase().indexOf(self.search().toLowerCase()) !== -1;
            })).sort(self.activeSort());
        } else {
            return result.sort(self.activeSort());
        }
    });

    self.removeFunctionalArea = function (FunctionalArea) {
        var con = confirm("Are you sure you want to delete this record?");
        if (con) {
            $.post(
                '/FunctionalAreas/Deactivate',
                AddAntiForgeryToken({ id: FunctionalArea.FunctionalAreaID }))
                .done(function () {
                    self.FunctionalAreas.remove(FunctionalArea)
                    //var parentRow = dataLink.parents("tr:first");
                    //parentRow.fadeOut('fast', function () {
                    //    parentRow.remove();
                    //});
                }).fail(function (data) {
                    alert("error");
                });
            return false;
        }
    }
    function _init() {
        //test code
        var data =[{ FunctionalAreaID: 1, FunctionalAreaName: 'Test', FunctionalAreaActive: true },
        { FunctionalAreaID: 2, FunctionalAreaName: 'atest', FunctionalAreaActive: true },
        { FunctionalAreaID: 3, FunctionalAreaName: 'ZTest', FunctionalAreaActive: false }];

        //real code
        //db.getFunctionalAreas(function (data) {
            var a = [];
            ko.utils.arrayForEach(data || [], function (item) {
                a.push(new sgsoip.FunctionalArea(item.FunctionalAreaID, item.FunctionalAreaName, item.FunctionalAreaActive));
            });
            self.functionalAreas(a);
       // });
    }
    _init();
    return {
        sort: sort,
        filteredItems: filteredItems,
        setActiveFilter: setActiveFilter,
        removeFunctionalArea: removeFunctionalArea
    }
}(ko);

ko.applyBindings(sgsoip.FunctionalAreaViewModel);</code></pre>
<pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/&gt;
&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"&gt;&lt;/script&gt;
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"&gt;&lt;/script&gt;
&lt;div class="container"&gt;
&lt;div class="row"&gt;
  &lt;div class="col-sm-2 col-md-1"&gt;
    &lt;label for="searchString"&gt;Search:&lt;/label&gt; 
  &lt;/div&gt;
  &lt;div class="col-sm-3"&gt;
    &lt;input name="searchString" class="form-control" id="searchString" type="text" value="" data-bind="value: search, valueUpdate: 'afterkeydown', event: { keyup: filteredItems } "&gt; 
  &lt;/div&gt;
  &lt;div class="col-sm-2 col-md-1"&gt;
    &lt;label for="Filter:"&gt;Filter:&lt;/label&gt;
  &lt;/div&gt;
  &lt;div class="col-sm-3"&gt;
    &lt;div class="btn-group" data-bind="foreach: filters"&gt;
      &lt;button class="btn btn-default" data-bind="click:  setActiveFilter, text: title"&gt;Show All&lt;/button&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
    
&lt;div class="row extraTopMargin"&gt;
  &lt;div class="col-sm-12"&gt;
    &lt;table class="table table-striped" id="gridoutput"&gt;
      &lt;thead&gt;
        &lt;tr data-bind="foreach: headers"&gt;
          &lt;th&gt;&lt;a href="#" data-bind="click: sort, text: title"&gt;&lt;/a&gt;&lt;/th&gt;
        &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody data-bind="foreach: filteredItems"&gt;
        &lt;tr&gt;
          &lt;td&gt;&lt;a href="javascript:void(0);" data-bind="click: removeFunctionalArea" title="Delete"&gt;&lt;i class="glyphicon glyphicon-trash"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/td&gt;
          &lt;td data-bind="text: FunctionalAreaName"&gt;&lt;/td&gt;
          &lt;td data-bind="text: FunctionalAreaActive"&gt;&lt;/td&gt;
        &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;</code></pre>
</div>
</div>
</p>

<p>If you type "z" you'll see that it works, but I get an error with developer tools open. If I remove the code for the search criteria from the computed, and just return result.sort(self.activeSort()); then no error occurs. All I'm doing is further refining the result array inside the computed, I am not sure that violates how a computed works, but perhaps I am.</p>