I had encountered the "Unable to read SObject" error when attempting to pass an SObject record from Lightning to an @AuraEnabled Apex method.
Based on this question, I first tried setting the "sobjectType". This was effecting when starting with a new record, but not when the record I wanted to save had first been queried from the database.
I knew I could stringify my record and pass the JSON string, which could then be deserialized in Apex, but running as a sys admin and using a very simple component, I should be able to successfully pass the SObject record directly into Apex.
Here is what I found...
The record from the database included an "attributes" attribute when viewing it stringified in the JavaScript console. This is not included when the component creates a new record.
{"attributes":{"type":"Application__c","url":"/services/data/v38.0/sobjects/Application__c/a0E2C000000RvHCUA0"},"Name":"test","Id":"a0E2C000000RvHCUA0"}
In order to get this SObject passed into Apex, I had to set "attributes" to null.
var appSobject = component.get("v.appSobject");
appSobject.attributes = null;
With or without setting "sobjectType", I was able to pass my queried record back into Apex when I cleared this "attributes" value before sending.
The error is also encountered when a query for the initial record traverses a relationship to include a related value, such as "Account__r.Name". In this case, I also had to set the "Account__r" attribute to null before passing the value into Apex.
I hope this information is helpful to someone in need.
Why do these attributes need to be set to null before passing the record back to Apex?