Handlebars.js: Handlebars: Access has been denied to resolve the property "..." because it is not an "own property" of its parent.

Created on 18 Jan 2020  ·  13Comments  ·  Source: handlebars-lang/handlebars.js

Since Handlebars 4.6.0, templates cannot access prototype properties and methods anymore (by default). See #1633 for discussios, reasons and justifications.

There are runtime options to restore and control the old behavior (see https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access), but if you are using a framework instead of Handlebars core, it might not be clear how to set them.

If you get this error message and please add a comment with the following information

  • Which framework (i.e express-hbs, express-handlebars) is calling Handlebars when the error is logged? (Paste the output of npm ls handlebars or yarn why handlebars, if unsure).
  • If you use Handlebars.compile and the resulting template-function directly, you answer should be here https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access. If the documentation doesn't answer your question or you don't understand it, please ask (here) so that the documentation can be improved.

Most helpful comment

Frameworks: express-handlebars in conjunction with mongoose

The models of Mongoose are classes and the properties are not "own properties" of the parent object.

The cleanest method is to make sure the the handlebars-input is a proper plain javascript object. This can be done in Mongoose, by calling toJSON() or toObject

app.get('/test', function (_req, res) {
    Kitten.find({}).then(kittens => {
        res.render('test.hbs', {
            kittens: kittens.map(kitten => kitten.toJSON())
        })
    })
});

The runtimeOptions (or templateOptions) mentioned in the documenation cannot be used here, because express-handlebars does not support setting them.

The quick-and-dirty hack (which is really hacky and I don't propose is), is to use

var handlebarsInstance = Handlebars.create();

handlebarsInstance.compile = function (templateStr, compileOptions) {
   // compile template
   // return a function that calls the compiled template with  `allowProtoPropertiesByDefault` and `allowProtoMethodsByDefault` as runtime-options
  // WARNING: People can crash your system by frabricating special templates. Don't use
  // this if your users can create templates. 
}
app.engine('hbs', expressHandlebars({
    handlebars: handlebarsInstance
}));

Please add a Rocket-emoji to this comment if you would like to have a Handlebars.createWithAllowedProtoAccess or something like that that does the middle part for you.

All 13 comments

Frameworks: express-handlebars in conjunction with mongoose

The models of Mongoose are classes and the properties are not "own properties" of the parent object.

The cleanest method is to make sure the the handlebars-input is a proper plain javascript object. This can be done in Mongoose, by calling toJSON() or toObject

app.get('/test', function (_req, res) {
    Kitten.find({}).then(kittens => {
        res.render('test.hbs', {
            kittens: kittens.map(kitten => kitten.toJSON())
        })
    })
});

The runtimeOptions (or templateOptions) mentioned in the documenation cannot be used here, because express-handlebars does not support setting them.

The quick-and-dirty hack (which is really hacky and I don't propose is), is to use

var handlebarsInstance = Handlebars.create();

handlebarsInstance.compile = function (templateStr, compileOptions) {
   // compile template
   // return a function that calls the compiled template with  `allowProtoPropertiesByDefault` and `allowProtoMethodsByDefault` as runtime-options
  // WARNING: People can crash your system by frabricating special templates. Don't use
  // this if your users can create templates. 
}
app.engine('hbs', expressHandlebars({
    handlebars: handlebarsInstance
}));

Please add a Rocket-emoji to this comment if you would like to have a Handlebars.createWithAllowedProtoAccess or something like that that does the middle part for you.

Estou com esse problema e não sei como consertar, pode me ajudar ?

Alguém sabe me informar como eu conserto esse erro quando vou usar o handlebars ?
Erro:
Pt-Br: handlebars: acesso negado para resolver a propriedade "nome" porque não é uma "propriedade própria" de seu pai.
Você pode adicionar uma opção de tempo de execução para desativar a verificação ou este aviso:

Does anyone know how to report this error when you use the handlebars?
Mistake:
En: handlebars: access denied to resolve the "name" property because it is not your father's "own property".

You can add a runtime option to disable verification or this warning:

O meu esta assim:
const handlebars = require('express-handlebars')

app.engine('handlebars', handlebars({defaultLayout: 'main'}))
app.set('view engine', 'handlebars')

app.get('/pagamento', function(req, res){
Pagamento.findAll().then(function(pagamentos){
res.render('pagamento', {pagamentos: pagamentos})
})

I would like to use the enhancement. En
Gostaria de usar o aprimoramento. Br

Have a look at this: https://www.npmjs.com/package/@handlebars/allow-prototype-access

The runtimeOptions (or templateOptions) mentioned in the documenation cannot be used here, because express-handlebars does not support setting them.

Since express-handlebars does not allow you to set these runtime configuration options, is anyone aware of a method to force express-handlebars to use handlebars 4.5.3?

You can use https://www.npmjs.com/package/@handlebars/allow-prototype-access with express-handlebars. It wraps the compiled template so that the default parameters are set.

Hi Nils, I am not able to get that package to work, when I try to run with that package I receive a "Error: Module "handlebars" does not provide a view engine." error. It appears another user is running into a similar problem in https://github.com/wycats/handlebars.js/issues/1648 . I posted my results in that same thread. Thanks

@craj1031tx I answered in #1648.

Frameworks: express-handlebars in conjunction with mongoose

The models of Mongoose are classes and the properties are not "own properties" of the parent object.

The cleanest method is to make sure the the handlebars-input is a proper plain javascript object. This can be done in Mongoose, by calling toJSON() or toObject

app.get('/test', function (_req, res) {
    Kitten.find({}).then(kittens => {
        res.render('test.hbs', {
            kittens: kittens.map(kitten => kitten.toJSON())
        })
    })
});

The runtimeOptions (or templateOptions) mentioned in the documenation cannot be used here, because express-handlebars does not support setting them.

The quick-and-dirty hack (which is really hacky and I don't propose is), is to use

var handlebarsInstance = Handlebars.create();

handlebarsInstance.compile = function (templateStr, compileOptions) {
   // compile template
   // return a function that calls the compiled template with  `allowProtoPropertiesByDefault` and `allowProtoMethodsByDefault` as runtime-options
  // WARNING: People can crash your system by frabricating special templates. Don't use
  // this if your users can create templates. 
}
app.engine('hbs', expressHandlebars({
    handlebars: handlebarsInstance
}));

Please add a Rocket-emoji to this comment if you would like to have a Handlebars.createWithAllowedProtoAccess or something like that that does the middle part for you.

Thanks dude :)

I leave the rocket there!

I'm using Express-Handlebars with Sequelize.
npm ls handlebars:

+-- [email protected]
| `-- [email protected] 
`-- [email protected] 

Console Output:

Handlebars: Access has been denied to resolve the property "name" because it is not an "own property" of its parent.
You can add a runtime option to disable the check or this warning:
See https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access for details
Handlebars: Access has been denied to resolve the property "id" because it is not an "own property" of its parent.
You can add a runtime option to disable the check or this warning:
See https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access for details
Handlebars: Access has been denied to resolve the property "email" because it is not an "own property" of its parent.
You can add a runtime option to disable the check or this warning:
See https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access for details
Handlebars: Access has been denied to resolve the property "url" because it is not an "own property" of its parent.
You can add a runtime option to disable the check or this warning:
See https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access for details
Handlebars: Access has been denied to resolve the property "description" because it is not an "own property" of its parent.
You can add a runtime option to disable the check or this warning:
See https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access for details
Handlebars: Access has been denied to resolve the property "createdAt" because it is not an "own property" of its parent.
You can add a runtime option to disable the check or this warning:
See https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access for details
Handlebars: Access has been denied to resolve the property "updatedAt" because it is not an "own property" of its parent.
You can add a runtime option to disable the check or this warning:
See https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access for details

I'll try your with your solution for mongoose

Frameworks: express-handlebars in conjunction with mongoose

The models of Mongoose are classes and the properties are not "own properties" of the parent object.

The cleanest method is to make sure the the handlebars-input is a proper plain javascript object. This can be done in Mongoose, by calling toJSON() or toObject

app.get('/test', function (_req, res) {
    Kitten.find({}).then(kittens => {
        res.render('test.hbs', {
            kittens: kittens.map(kitten => kitten.toJSON())
        })
    })
});

The runtimeOptions (or templateOptions) mentioned in the documenation cannot be used here, because express-handlebars does not support setting them.

The quick-and-dirty hack (which is really hacky and I don't propose is), is to use

var handlebarsInstance = Handlebars.create();

handlebarsInstance.compile = function (templateStr, compileOptions) {
   // compile template
   // return a function that calls the compiled template with  `allowProtoPropertiesByDefault` and `allowProtoMethodsByDefault` as runtime-options
  // WARNING: People can crash your system by frabricating special templates. Don't use
  // this if your users can create templates. 
}
app.engine('hbs', expressHandlebars({
    handlebars: handlebarsInstance
}));

Please add a Rocket-emoji to this comment if you would like to have a Handlebars.createWithAllowedProtoAccess or something like that that does the middle part for you.

We can alose use lean() method as shown below

 app.get('/test', function (_req, res) {
    Kitten.find().lean().then(kittens => res.render('test.hbs', { kittens: kittens}));
});

Since express-handlebars does not allow you to set these runtime configuration options, is anyone aware of a method to force express-handlebars to use handlebars 4.5.3?

I created a PR to allow adding runtime configuration options to express-handlebars. https://github.com/express-handlebars/express-handlebars/pull/53

Was this page helpful?
0 / 5 - 0 ratings