Hello! I have that struct in go:
import (
"go.mongodb.org/mongo-driver/bson/primitive"
)
type User struct {
ID primitive.ObjectID `json:"_id" bson:"_id,omitempty"`
Username string `bson:"username"`
PasswordHash string `bson:"password_hash"`
Permissions Permissions `json:"permissions" bson:"permissions"`
}
And I can’t decode *mongo.SingleResult into my type:
` usersCollection := mongoClient.Database(“test”).Collection(“users”)
user := auth.User{
Username: "anyuser",
PasswordHash: "somehash",
Permissions: auth.NewPermissions(auth.PermissionUser),
}
if _, err := usersCollection.InsertOne(ctx, user); err != nil {
panic(err)
}
singleResult := usersCollection.FindOne(ctx, bson.D{})
if singleResult.Err() != nil {
panic(singleResult.Err())
}
var userResult auth.User
err = singleResult.Decode(&userResult)
It fails with:
panic: error decoding key _id: cannot decode objectID into an array
goroutine 1 [running]:
main.main()
./tmp.go:51 +0x505
exit status 2
`
Hi @Goshleg_N_A , which version of the Go Driver are you using?
Your issue is likely due to the way you’re inserting the document into MongoDB. Since the User
struct has ID
of type primitive.ObjectID
, but you’re not explicitly setting it when inserting, MongoDB generates an _id
field of type ObjectID
automatically. However, your user
struct lacks an ID
field during insertion, which means MongoDB might be storing _id
in an unexpected format.
Solution
1. Ensure ID
is set before inserting
Modify the User
struct instance before inserting it:
user := auth.User{
ID: primitive.NewObjectID(), // Generate a new ObjectID
Username: "anyuser",
PasswordHash: "somehash",
Permissions: auth.NewPermissions(auth.PermissionUser),
}
This ensures that _id
is stored as a primitive.ObjectID
.
2. Use bson.M{}
or bson.D{}
for querying
Your query bson.D{}
(empty filter) should work, but to be explicit, try:
singleResult := usersCollection.FindOne(ctx, bson.M{"username": "anyuser"})
This ensures you’re fetching a document that exists.
3. Check Decoding Again
After making the above changes, try decoding again:
var userResult auth.User
if err := singleResult.Decode(&userResult); err != nil {
panic(err)
}
fmt.Println("User retrieved:", userResult)
Explanation of the Error
The error message cannot decode objectID into an array
suggests that MongoDB might be returning an _id
of a different type or an unexpected structure.
MongoDB automatically assigns an _id
field as ObjectID
when not explicitly set.
If you inserted a document without ID
, MongoDB might be handling _id
in a way that Go’s BSON decoding doesn’t expect.
1 Like
Matt_Dale
(Matt Dale)
January 29, 2025, 3:09am
4
@Goshleg_N_A Is it possible you’re mixing Go Driver v1.x and v2.x packages? I was able to reproduce the error you’re seeing with this example:
package main
import (
"context"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/v2/mongo"
)
func main() {
mongoClient := mongo.Connect()
type User struct {
ID primitive.ObjectID `json:"_id" bson:"_id,omitempty"`
Username string `bson:"username"`
PasswordHash string `bson:"password_hash"`
}
usersCollection := mongoClient.Database("test").Collection("users")
ctx := context.TODO()
user := User{
Username: "anyuser",
PasswordHash: "somehash",
}
if _, err := usersCollection.InsertOne(ctx, user); err != nil {
panic(err)
}
var userResult User
err := usersCollection.FindOne(ctx, bson.D{}).Decode(&userResult)
if err != nil {
panic(err)
}
}
Notice that primitive.ObjectID
comes from the non-v2 package. Try changing that type to bson.ObjectID
and see if it resolves your problem.
Thank you so much !! Had the same problem. Works !