Decode Argon2 parameters and handling decode errors
Because you use named parameters, the error checking can indeed be simplified.

While you critique the use of if err != nil, I enjoy the consistent error handling, and prefer it to the concepts used in many other languages.

Returning errors

Rather than explicitly returning values, such as

return nil, nil, nil, errors.New("...")


You can instead set the named return value err:

if len(fields) != 6 {
    err = errors.New("incorrect hash format")
    return
}


This does not set the other values to nil, and that shouldn't matter. In terms of consuming this API, it would be bad practice to use any other return values if err is not nil. It would be the equivalent in C of using the return value of strtoul() without checking errno.

Having the comment // error check each time is too verbose.

Misspelling

The variable fileds is misspelled, it should be fields.

Helper function

Using named return values in your helper function is superfluous. You can easily return those variables directly.

func decodeBase64WithLength(encStr string) ([]byte, uint32, error) {
    s, err := base64.RawStdEncoding.DecodeString(encStr)
    return s, uint32(len(s)), err
}


But now that the function has been cleaned up, it's easy to see that it really isn't needed. If this is the only place you use the function, then doing something small twice doesn't justify a helper function in my opinion.

Params

You reference Argon2Params as Params, and both are exported types, but you refer to its members as unexported types. I'll assume it's exported, and capitalize the member variables.

Conclusion

Here is the code I ended up with:

package main

import (
    "encoding/base64"
    "errors"
    "fmt"
    "strings"

    "golang.org/x/crypto/argon2"
)

// Argon2Params are ...
type Argon2Params struct {
    Memory     uint32
    Time       uint32
    Threads    uint8
    SaltLength uint32
    KeyLength  uint32
}

func decodeHash(encodedHash string) (p *Argon2Params, salt, hash []byte, err error) {
    fields := strings.Split(encodedHash, "$")

    if len(fields) != 6 {
        err = errors.New("incorrect hash format")
        return
    }

    var version int

    if _, err = fmt.Sscanf(fields[2], "v=%d", &amp;version); err != nil {
        return
    }

    if version != argon2.Version {
        err = errors.New("argon2 version mismatch")
        return
    }

    p = &amp;Argon2Params{}

    if _, err = fmt.Sscanf(fields[3], "m=%d,t=%d,p=%d", &amp;p.Memory, &amp;p.Time,
        &amp;p.Threads); err != nil {
        return
    }

    salt, err = base64.RawStdEncoding.DecodeString(fields[4])
    p.SaltLength = uint32(len(salt))

    if err != nil {
        return
    }

    hash, err = base64.RawStdEncoding.DecodeString(fields[5])
    p.KeyLength = uint32(len(hash))

    return
}

func main() {
    decodeHash("$argon2id$v=19$m=65536,t=3,p=4$ruDgwQK24h0wGXI87+lVWAbHmgNidUNPVSTdSloOlfM$py20HR7L4K6LllGsZNDbkrbh89x2tIF8JCIG0DAaoi8")
}


Hope this helps!