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 !