It's a combination of two things. First, type inference from "short variable declaration" (see the spec here: https://golang.org/ref/spec#Short_variable_declarations ) and secondly, nil interfaces vs typed nils stored in an interface type (see this FAQ entry https://golang.org/doc/faq#nil_error ).
Another way to explain the difference is the following:
// case 1 is the same as
var i int
// inferred type of *MyErr because that's what returnsNilError returns
var err *MyErr
i, err = 0, (*MyErr)(nil)
// err is of type (nil)(*MyErr)
// case 2 is the same as
// inferred type of error because os.Open returns that
var err error
err = os.Open("/tmp/file")
var i int
i err = 0, (error)((*MyErr)(nil))
// err is of type (error)((*MyErr)(nil))
Note well that "err" is a different type in those two cases. Type inference, plus the fact that short variable decleration re-uses an existing variable if the type is compatible, can result in previous code changing what type a variable is.It's well known that an interface with a type is != nil (i.e. "var nilErr *MyErr = nil; var errIface error = nilErr" results in an 'errIface' that is not equal to an untyped nil).
I hope that explanation made sense to you.