Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

encoding/gob: "wrong type for received field" when decoding slices of pointers #2995

patrickmn opened this issue Feb 12, 2012 · 5 comments


Copy link

@patrickmn patrickmn commented Feb 12, 2012

What steps will reproduce the problem?
1. Try to encode, then decode a []*Object where Object.Children = []*Object

What is the expected output?
No error

What do you see instead? In Decoder.Decode: "gob: wrong type ([]*main.Object) for
received field .Children"
(because Object.Children[0].Children is nil?)

Which compiler are you using (5g, 6g, 8g, gccgo)? 6g

Which operating system are you using? Linux

Which revision are you using? 7e665c5da059 tip


This only seems to happen when you haven't first set a precedent by encoding a []Object
(regardless if it's a different encoder). Running gob.Register on an []Object does not
have the same effect.

package main

import (

type Object struct {
    Num      int
    Children []*Object

func TestGobPtrSlices(t *testing.T) {
    var err error
    b := &bytes.Buffer{}

    // Works if you uncomment this
    // fos := []Object{
    //  Object{1, nil},
    //  Object{2, nil},
    // }
    // err = gob.NewEncoder(b).Encode(&fos)
    // if err != nil {
    //  t.Fatal("Couldn't encode:", err)
    // }
    // var nfos []Object
    // err = gob.NewDecoder(b).Decode(&nfos)
    // if err != nil {
    //  t.Fatal("Couldn't decode:", err)
    // }

    os := []*Object{
        &Object{1, nil},
        &Object{2, nil},
    err = gob.NewEncoder(b).Encode(&os)
    if err != nil {
        t.Fatal("Couldn't encode:", err)

    var nos []*Object
    err = gob.NewDecoder(b).Decode(&nos)
    if err != nil {
        t.Fatal("Couldn't decode:", err)
    for _, v := range nos {
        assert(t, v)

func assert(t *testing.T, o *Object) {
    if o.Num != 1 && o.Num != 2 {
        t.Error("o.Num not 1 or 2, but", o.Num)
    for _, v := range o.Children {
        assert(t, v)
Copy link

@rsc rsc commented Feb 14, 2012

Comment 1:

Does look like a bug: the only difference I see between the commented-out
code and the not-working code is that the former uses []Object instead of []*Object.
There are no nil pointers being transmitted as part of a slice (but there are nil

Labels changed: added priority-go1, go1-must, removed priority-triage.

Owner changed to @robpike.

Status changed to Accepted.

Copy link

@patrickmn patrickmn commented Feb 15, 2012

Comment 2:

The strange thing is that the decoding of the []*Object will actually work if you
uncomment the first block (when it has decoded/registered in some Gob global an []Object
I figured it would be due to an []Object being gob.Register'ed first, but doing that did
not have the same effect.
Copy link

@robpike robpike commented Feb 17, 2012

Comment 3:

Nice bug. Thanks for the excellent simple example.
Fix out for review.

Status changed to Started.

Copy link

@patrickmn patrickmn commented Feb 17, 2012

Comment 4:

Most welcome.
Copy link

@robpike robpike commented Feb 18, 2012

Comment 5:

This issue was closed by revision 793f6f3.

Status changed to Fixed.

@rsc rsc added this to the Go1 milestone Apr 10, 2015
@rsc rsc removed priority-go1 labels Apr 10, 2015
@golang golang locked and limited conversation to collaborators Jun 24, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants
You can’t perform that action at this time.