I think this was because I was calling a mutable function from a non-mutable function using a read. I changed the definition of external_function
to be non-mutating, ran cargo clean
in the cross calling contract, redeployed, and then it started to work.
#[ink(message)]
pub fn external_function(
&self, // mut is gone
...
EDIT: This can also happen if your cached version of the contract from github is out of date. In this case, delete the cached version of the contract so that it is downloaded again.
e.g. delete this /usr/local/cargo/git/checkouts/THE-CONTRACT-9b59cb28149dd121/c56b619/contracts/lib.rs