Smart Action - Prefill a form with default values not working in Production

Feature(s) impacted

Smart Action - Prefill a form with default values, using the hook feature

Observed behavior

The input is prefilled in development environment but when I try it in production, it does not work anymore.
Forest throws the following error : An error occured on form load. Check your server logs for more details.

Expected behavior

I expect the input to prefill the value, which is the actual behaviour in development.

Failure Logs

My server logs :

Processing by ForestLiana::ActionsController#load as JSON
2022-01-11T18:45:52.824157+00:00 app[web.1]: I, [2022-01-11T18:45:52.824135 #4]  INFO -- : [b5a53444-521c-4593-a922-997cd3b8d8f7]   Parameters: {"data"=>{"attributes"=>{"ids"=>["2"], "collection_name"=>"TransferCode", "parent_collection_name"=>nil, "parent_collection_id"=>nil, "parent_association_name"=>nil, "all_records"=>false, "all_records_subset_query"=>{}, "all_records_ids_excluded"=>[], "smart_action_id"=>"888a90b0-83f5-11ea-864f-09ec8b4f03af"}, "type"=>"action-requests"}, "timezone"=>"Europe/Paris", "action_name"=>"creer-un-versement-membre"}
2022-01-11T18:45:52.824286+00:00 app[web.1]: W, [2022-01-11T18:45:52.824263 #4]  WARN -- : [b5a53444-521c-4593-a922-997cd3b8d8f7] HTTP Origin header (https://app.forestadmin.com) didn't match request.base_url (https://ichangedthenameofmyapp.herokuapp.com)
2022-01-11T18:45:52.824526+00:00 app[web.1]: I, [2022-01-11T18:45:52.824490 #4]  INFO -- : [b5a53444-521c-4593-a922-997cd3b8d8f7] Completed 422 Unprocessable Entity in 0ms (ActiveRecord: 0.0ms)
2022-01-11T18:45:52.825099+00:00 app[web.1]: F, [2022-01-11T18:45:52.825064 #4] FATAL -- : [b5a53444-521c-4593-a922-997cd3b8d8f7]
2022-01-11T18:45:52.825101+00:00 app[web.1]: F, [2022-01-11T18:45:52.825088 #4] FATAL -- : [b5a53444-521c-4593-a922-997cd3b8d8f7] ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):

Context

  • Project name: Culturepay
  • Environment name: Production
    I am using forest_liana (7.4.5)

Hello @juliepierre ! :wave: Welcome to our community :tada: :confetti_ball:

Thanks for this detailed thread. :pray:
I just need a few other information to help us find the culprit.

  • Can also provide the details about the error received from your agent, it would help ? This can be done using the developer tools of your browser → Network tab.
  • Could you, also, share the code of the smart action load hooks ?

Thanks in advance.

Kind regards,
Morgan

Hello Morgan !

Sure, there you have. FYI, I reproduced the issue on my staging environment, so here you will have the details from my staging app, but it is exactly the same issue on the live app.

The code of the smart action with the hooks

action "Créer un Versement Membre",
    type: 'single',
    fields: [
    {
      field: 'Montant en centimes',
      description: "Renseigner le montant du Versement Membre en centimes",
      type: 'Number',
      is_required: true
    },
    {
      field: 'Description',
      description: "Ajouter une description",
      type: 'String',
      is_required: true
    }],
    hooks: {
      :load => -> (context){
        description = context[:fields].find{|field| field[:field] == 'Description'}

        id = context[:params][:data][:attributes][:ids][0]
        transfer_code = TransferCode.find(id)

        description[:value] = "Versement #{transfer_code.member.company_name} #{transfer_code.validity_month.strftime('%m/%Y')}"

        return context[:fields]
      }
    }

The error from client
[forest] 🌳🌳🌳 Unexpected error on Smart Action Form load hook retrieval HttpError: HTTP Error 422: Unprocessable Entity

Failure ~>

Request details ~>

And the whole Request Headers ~>

POST /forest/actions/creer-un-versement-membre/hooks/load?timezone=Europe%2FParis HTTP/1.1
Host: staging-culturepay.herokuapp.com
Connection: keep-alive
Content-Length: 324
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="96", "Google Chrome";v="96"
Accept: application/json
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJpZCI6IjE5NTQ1IiwiZW1haWwiOiJqdWxpZS5waWVycmUzQGdtYWlsLmNvbSIsImZpcnN0X25hbWUiOiJKdWxpZSIsImxhc3RfbmFtZSI6IlBpZXJyZSIsInRlYW0iOiI-IERhaWx5IE9wcyIsInJvbGUiOm51bGwsInRhZ3MiOltdLCJyZW5kZXJpbmdfaWQiOiI1ODU0NiIsImV4cCI6IjE2NDE5ODU1MjIifQ.JoCHlS6IGD_fGQUMRU1tVnBoNf_Q8kYVJuGOPRUY1PE
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36
sec-ch-ua-platform: "macOS"
Origin: https://app.forestadmin.com
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://app.forestadmin.com/
Accept-Encoding: gzip, deflate, br
Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7

Hey @juliepierre :wave:

The logs you mentionned in your first message indicate ActionController::InvalidAuthenticityToken.
Would it be possible to see the associated code ? (As DM if you consider it private, here otherwise)

Thanks :pray:

Hello ! :wave:

I’m working on the same project and we are trying again to add a smart action prefilled with default values. We still encounter the same issue as above when we deploy : HTTP Origin header (https://app.forestadmin.com) didn't match request.base_url (https://ichangedthenameofmyapp.herokuapp.com).

We are currently using the gem forest_liana (7.7.3) / Rails 6.0.5.1 with Ruby 3.0.5.

Thanks for your help,

Diane

Hey @DianeCP

Would it be possible for you to share your smart action definition, as well as your project name ?

Thanks in advance

Hello !

The project name is Culturepay

Smart Action Definition:

  action "Modifier un intermittent",
         type: 'single',
         fields: [{
           field: 'Genre',
           type: 'String',
           is_required: false
         }, {
           field: 'Nom',
           type: 'String',
           is_required: false
         }, {
           field: 'Prénom',
           type: 'String',
           is_required: false
         }, {
           field: 'Téléphone',
           type: 'String',
           is_required: false
         }, {
           field: 'Email',
           type: 'String',
           is_required: false
         }, {
           field: 'Adresse',
           type: 'String',
           is_required: false
         }, {
           field: 'Code Postal',
           type: 'String',
           is_required: false
         }, {
           field: 'Ville',
           type: 'String',
           is_required: false
         }, {
           field: 'Pays',
           type: 'String',
           is_required: false
         }, {
           field: 'Nationalité',
           type: 'String',
           is_required: false
         }, {
           field: 'Date de naissance',
           type: 'Date',
           is_required: false
         }, {
           field: 'Lieu de naissance',
           type: 'String',
           is_required: false
         }, {
           field: 'Pays de naissance',
           type: 'String',
           is_required: false
         }, {
           field: 'Numéro de sécurité sociale',
           type: 'String',
           is_required: false
         }, {
           field: 'Numéro congés spectacle',
           type: 'String',
           is_required: false
         }],
         hooks: {
           load: lambda do |context|
             gender = context[:fields].find { |field| field[:field] == 'Genre' }
             last_name = context[:fields].find { |field| field[:field] == 'Nom' }
             first_name = context[:fields].find { |field| field[:field] == 'Prénom' }
             phone_number = context[:fields].find { |field| field[:field] == 'Téléphone' }
             email = context[:fields].find { |field| field[:field] == 'Email' }
             address = context[:fields].find { |field| field[:field] == 'Adresse' }
             zip_code = context[:fields].find { |field| field[:field] == 'Code Postal' }
             city = context[:fields].find { |field| field[:field] == 'Ville' }
             country = context[:fields].find { |field| field[:field] == 'Pays' }
             nationality_country = context[:fields].find { |field| field[:field] == 'Nationalité' }
             birth_date = context[:fields].find { |field| field[:field] == 'Date de naissance' }
             birth_city = context[:fields].find { |field| field[:field] == 'Lieu de naissance' }
             birth_country = context[:fields].find { |field| field[:field] == 'Pays de naissance' }
             social_security_number = context[:fields].find { |field| field[:field] == 'Numéro de sécurité sociale' }
             conges_spectacle_number = context[:fields].find { |field| field[:field] == 'Numéro congés spectacle' }

             id = context[:params][:data][:attributes][:ids][0]
             employee = Employee.find(id)

             gender[:value] = employee.gender
             first_name[:value] = employee.first_name
             last_name[:value] = employee.last_name
             phone_number[:value] = employee.phone_number
             email[:value] = employee.email
             address[:value] = employee.address
             zip_code[:value] = employee.zip_code
             city[:value] = employee.city
             country[:value] = employee.country
             nationality_country[:value] = employee.nationality_country
             birth_date[:value] = employee.birth_date
             birth_city[:value] = employee.birth_city
             birth_country[:value] = employee.birth_country
             social_security_number[:value] = employee.social_security_number
             conges_spectacle_number[:value] = employee.conges_spectacle_number

             context[:fields]
           end
         }

We have the same issue as before and we never managed to fix the previous one (Julie’s smart action is online but without default values).

Thanks

I just looked in our forest_liana code and there is no reference of this InvalidAuthenticityToken. Do you use any gem that can interfer with the forestadmin authentication on the agent side? Could you share here the route declaration for this action ?

Thanks in advance

I think InvalidAuthenticityToken is an error raised by Rails but triggered by the request origin problem. I am not sure which gem could interfere with forest authentication, however it seems to be the only use case where we have a problem (and only in production environments), otherwise the authentication works fine.

The route declaration is:

namespace :forest do
    post 'actions/modifier-un-intermittent' => 'employees#update_employee'
 end

=> creates the following route : forest_actions_modifier_un_intermittent POST /forest/actions/modifier-un-intermittent(.:format) forest/employees#update_employee

Thanks

Hey :wave:

Any way you can share both the complete HTTP request and response that is failling ?

I can’t spot any specific issue with this action on my end. However, I can see a few changes regarding smart action between the 7.4.5 (If that’s still the one you are using) and our latest v7 (7.8.0). Can you try to upgrade and see if anything changes?

Thanks in advance :pray:

Hello ! :wave:

Please find below the details of the request and response.

Response Headers

HTTP/1.1 422 Unprocessable Entity
Server: Cowboy
Date: Mon, 20 Mar 2023 15:25:20 GMT
Connection: keep-alive
Access-Control-Allow-Origin: https://app.forestadmin.com
Access-Control-Allow-Methods: GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS
Access-Control-Expose-Headers: Content-Disposition
Access-Control-Max-Age: 7200
Access-Control-Allow-Credentials: true
Content-Type: application/json; charset=UTF-8
X-Request-Id: bd92b9b7-028a-45a4-bee4-fd484e850747
X-Runtime: 0.003616
Strict-Transport-Security: max-age=31536000; includeSubDomains
Vary: Origin
Content-Length: 45
Via: 1.1 vegur

Request Headers

POST /forest/actions/modifier-un-intermittent/hooks/load?timezone=Europe%2FParis HTTP/1.1
Accept: application/json
Accept-Encoding: gzip, deflate, br
Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7
Authorization: TOKEN_HIDDEN
Connection: keep-alive
Content-Length: 947
Content-Type: application/json
Host: staging-culturepay.herokuapp.com
Origin: https://app.forestadmin.com
Referer: https://app.forestadmin.com/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36
sec-ch-ua: "Google Chrome";v="111", "Not(A:Brand";v="8", "Chromium";v="111"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"

(Authorization contains a token in the real header, we changed it here)

We are using 7.7.3 at the moment

Thanks

Would it also be possile to get the Controller as well ? (As DM if, again, you don’t want to share it publicly here :slight_smile: )

1 Like