mongo_orm Exception: missing bson key: publish_acl (Exception)

When you extend your field definitions in the mongo_orm document classes, specifically with embedded documents, you might run into the following runtime (!) error:

Exception: missing bson key: <name> (Exception)

This is not an error in your code – your code is raising, because the database structure is not as it expects it to be!

Here’s the sample code which I am using for creating a Mongo Auth & ACL DB for VerneMQ:

class PublishACL < Mongo::ORM::EmbeddedDocument
     field pattern : String
     field max_qos : Int32
     field allowed_retain : Bool
     field max_payload_size : Int32

class SubscribeACL < Mongo::ORM::EmbeddedDocument
     field pattern : String
     field max_qos : Int32

class MQTTCredentials < Mongo::ORM::Document
     collection_name “vmq_acl_auth”
     field mountpoint : String
     field client_id : String
     field username : String
     field passhash : String
     embeds_many :publish_acl, class_name: Papi::PublishACL 
     embeds_many :subscribe_acl, class_name: Papi::SubscribeACL

# keys are unique per apikey_prefix
def self.getcredentials(apikey_prefix : String, bcm_serial : String)
     success = false
     #if the credentials don’t exist yet, they are added
     creds = self.first({“client_id” => bcm_serial, “username” => apikey_prefix})
     if !creds
         creds =


    publish_acl =
     subscribe_acl =
     publish_acl.pattern = “#”
     publish_acl.max_qos = 2  # Int
     publish_acl.allowed_retain = true

    subscribe_acl.pattern = “#”
     subscribe_acl.max_qos = 2
     creds.publish_acl <<  publish_acl
     creds.subscribe_acl << subscribe_acl 
     success =




The ACLs were inserted after I already had database entries without them:


MongoORM error message:

Exception: missing bson key: publish_acl (Exception)
   from src/ in ‘from_bson’
   from lib/mongo_orm/src/mongo_orm/ in ‘all’
   from lib/mongo_orm/src/mongo_orm/ in ‘all’


  from /usr/share/crystal/src/ in ‘->’
   from ???

MongoORM does not find the expected fields publish_acl and subscribe_acl, which were added later.

Solution: drop (or upgrade) the documents in the Collection, which do not conform to your new standard.

This is, for instance, how a database entry looks like for the above:



in lib/mongo_orm/src/mongo_orm/ no overload matches ‘BSON#[]=’ with types String, Array(Papi::PublishACL)

Overloads are:

– BSON#[]=(key, value : Int32)

– BSON#[]=(key, value : Int64)

– BSON#[]=(key, value : Binary)

– BSON#[]=(key, value : Bool)

– BSON#[]=(key, value : Float64 | Float32)

– BSON#[]=(key, value : MinKey)

– BSON#[]=(key, value : MaxKey)

– BSON#[]=(key, value : Nil)

– BSON#[]=(key, value : ObjectId)

– BSON#[]=(key, value : String)

– BSON#[]=(key, value : Symbol)

– BSON#[]=(key, value : Time)

– BSON#[]=(key, value : Timestamp)

– BSON#[]=(key, value : Code)

– BSON#[]=(key, value : BSON)

– BSON#[]=(key, value : Regex)

– BSON#[]=(key, value : Mongo::ORM::EmbeddedDocument)

bson[_key] = value

You cannot do this (currently) with MongoORM:

creds.publish_acl = [ publish_acl ]

instead you have to use:

creds.publish_acl <<  publish_acl