Well, the dynamic version won't complain until runtime the day you mix up the order of your parameters and invoke "create(params, conn)", for instance. Besides, you can make it statically impossible to generate an invalid user object with a static language. In a dynamic language, an invalid user object is just an assignation away.
Now, if we are talking about error handling, the way it is done in Go is not particularly representative. Most static languages would go with exceptions (or maybe checked exceptions in Java). Haskell/Rust/Scala would probably go with a Result type, and then it's more a question of the language giving you the tools to propagate the errors and wrap them (Rust with error-chain is excellent at this kind of thing).