The reasons your 2nd short assignment gets through is because value2 is indeed new to “delcare and define”. Go allows multiple short assignments only there is new variable.
HOWEVER, the above is not applicable for assignment in reference (e.g. struct field). In that case, you need to declare the err variable first then assign accordingly. Example, this won’t work:
s := &MyStruct{A: 0} // some kind of struct
s.A, err := somefunc(...) // err is new variable
This works:
var err error
s := &MyStruct{A: 0} // some kind of struct
s.A, err = somefunc(...)
Explanation
Short assignment is merely a “shortcut” to declare and define, example:
value2 is indeed requiring declaration. If I break it down:
value1, err := "v1", "e1" # value 1 = [Declare and Define], err = [Declare and Define]
...
value2, err := "v2", "e2" # value 2 = [Declare and Define], err = [Define]
...
value3, err := "v3", "e3" # value 3 = [Declare and Define], err = [Define]
...
value2, err = "v4", "e4" # value 2 = [Define], err = [Define]
...
value2, err := "v5", "e5" # ERROR: value 2 = [RE-Declare and Define], err = [RE-Declare and Define]
Go accepts this short assignment when it comes to multiple variables. Your second example is aligned to my explanation (err should be the same object).
Unlike regular variable declarations, a short variable declaration may redeclare variables provided they were originally declared earlier in the same block (or the parameter lists if the block is the function body) with the same type, and at least one of the non-blank variables is new. As a consequence, redeclaration can only appear in a multi-variable short declaration. Redeclaration does not introduce a new variable; it just assigns a new value to the original.