Update:
As far as I can see now in Spring 2019 version, this issue can no longer be reproduced even if I set API Version to older one for both the Lightning Application and Apex Controller. The issue seems to be fixed now, so no workaround anymore needed (like workaround described below to change signature of Apex method to Decimal mu(Decimal a, Decimal b).
Old issue explanation and workaround:
It is not obvious reading the Salesforce documentation
Number
An input field for entering a number. When working with
numerical input, you can use attributes like max, min, and step.
<lightning:input type="number" name="number" label="Number"
value="12345"/>
To format numerical input as a percentage or currency,
set formatter to percent or currency respectively.
<lightning:input type="number" name="ItemPrice"
label="Price" value="12345" formatter="currency"/>
Fields for percentage and currency input must specify a step increment of 0.01 as
required by the native implementation.
<lightning:input type="number" name="decimal" label="Enter a decimal
value" step="0.001"/>
<lightning:input type="number"
name="percentVal" label="Enter a percentage value" formatter="percent"
step="0.01" />
<lightning:input type="number" name="currencyVal"
label="Enter a dollar amount" formatter="currency" step="0.01" />
that Lightning passes every number as Decimal
typed value disregarding if it is actually Integer
or Decimal
.
This becomes clear when you implement getType
method and debug type of the input variables
public static string getType(Object o) {
if(o==null) return ''; // we can't say much about null with our current techniques
if(o instanceof SObject) return ((SObject)o).getSObjectType().getDescribe().getName()+'';
if(o instanceof Boolean) return 'Boolean';
if(o instanceof Id) return 'Id';
if(o instanceof String) return 'String';
if(o instanceof Blob) return 'Blob';
if(o instanceof Date) return 'Date';
if(o instanceof Datetime) return 'Datetime';
if(o instanceof Time) return 'Time';
if(o instanceof String) return 'String';
if(o instanceof Integer) return 'Integer';
if(o instanceof Long) return 'Long';
if(o instanceof Decimal) return 'Decimal'; // we can't distinguish between decimal and double
if(o instanceof Double) return 'Double'; // we can't distinguish between decimal and double
if(o instanceof List<object>) return 'List';
return 'Object'; // actually we can't detect maps and sets and maps
}
@auraEnabled
public static Decimal mu(Decimal a, Integer b){
System.debug(LoggingLevel.ERROR, '@@@ a: ' + a );
System.debug(LoggingLevel.ERROR, '@@@ b: ' + b );
System.debug(LoggingLevel.ERROR, getType( a ) );
System.debug(LoggingLevel.ERROR, getType( b ) );
return a * b;
}
When you look at debug logs you will see that types of both input variables are Decimal
, not Integer
,
14:10:36:005 USER_DEBUG [27]|ERROR|Decimal
14:10:36:005 USER_DEBUG [28]|ERROR|Decimal
despite one might expect type of second input variable to be Integer
since its attribute is declared as Integer
, not as Decimal
.
<aura:attribute name="bb" type="Integer" default="10" description="Integer number b"/>
So, the solution for this would be change input variable type to Decimal
, if you make this simple change
@auraEnabled
public static Decimal mu(Decimal a, Decimal b){
return a * b;
}
you will see that the code executes successfully

So you don't have always convert any value to String to pass it from Lightning to Apex, sometimes it is enough just to have declaration change.
Fix for this issue(W-5724071) is in the upcoming patch (scheduled to be released in mid Jan).
In Spring'19 salesforce is addressing various long standing issues with deserialization pertaining to apex actions. Brief list of enhancements include,
- Make conversion of all primitive apex data types work for positive use cases. There were a few reported issues here by the community (e.g. link).
- Make incorrect usage error out with a clear develop error. Currently any incorrect usage results in internal server error (resulting in noise for us and useless stack-id for developer)
- Add support POJO style user defined Apex types
- Make handing of SObjects consistent
- Add support for nested lists/maps
I have also reached out to documentation team to ensure more details of the enhancements get incorporated in the public docs.
Best Answer
Usually this happens when you assign a string to an ID variable which turns out to be an invalid id (string should be valid 15 or 18 digit id). In your case please check whether string variable assigned to ID variable is not a blank or invalid id.