Validation messages for second setting not displayed

On a published app, I noticed the following strange behavior (which differs from the one during development):
Two parameters are validated (by adding an event handler to each field using the “change” event in iparams.json) via an outside request.
If the first parameter is faulty, this is displayed to the user after the result of the outside request has been received.
If the second parameter is faulty, no message is displayed to the user, although the remote call is successfull and returns the appropriate result, as visible by an entry in the browser console.
No javascript errors are shown and the remote call is identical (although different parts of the response are used).
Why isn’t the feedback displayed? (Especially, as it was working during development.)

Here is the code from iparams.js:

  async function(_client) {
    window.client = _client;
  }
);

async function checkSubdomain(newValue) {
  var ocSubdomain = utils.get('ocSubdomain');
  if (ocSubdomain == '') return true;
  var ocSecretKey = utils.get('ocSecretKey');
  var fdSubdomain = utils.get('fdSubdomain');
  if (fdSubdomain == '') return 'Please enter your Freshdesk subdomain below, so the settings may be tested.';
  try{
    let test_result;
    test_result = await (client.request.invokeTemplate("connectionTest", { "context": { "ocSubdomain": ocSubdomain, "fdSubdomain": fdSubdomain, "ocSecretKey": ocSecretKey } }));
    console.log('checkSubdomain result arrived: ' + test_result.response);
    if ((test_result.status != 200) || (test_result.headers['content-type']!='application/json;charset=utf-8')){
      return 'No connection possible. Check your subdomain or try later.';
    }
    const response = JSON.parse(test_result.response);
    if (!response.onecockpit){
      return 'No OneCockpit installation detected.';
    }else{
      var errors = [];
      if (!response.active){
        errors.push('Your Freshdesk integration is set to inactive.');
      }
      if (!response.apikey_exists){
        errors.push('You need to enter your Freshdesk API key in your OneCockpit installation.');
      }
      if (!response.subdomain_exists){
        errors.push('You need to enter your Freshdesk subdomain in your OneCockpit installation.');
      }else if (!response.subdomain_matches){
        errors.push('Your Freshdesk subdomain does not match the one entered in your OneCockpit installation.');
      }
      if (errors.length > 0){
        let result = errors.join(' <br>');
        return result;
      }
    }
  }catch(err){
    console.log(err);
    return 'No connection possible now. Check your subdomain or try later.';
  }
  return '';
}

async function checkSecretKey(newValue) {
  var ocSubdomain = utils.get('ocSubdomain');
  var fdSubdomain = utils.get('fdSubdomain');
  var ocSecretKey = utils.get('ocSecretKey');
  if (ocSubdomain == '') return 'Please enter your OneCockpit subdomain first.';
  if (fdSubdomain == '') return 'Please enter your Freshdesk subdomain below, so the settings may be tested.';
  try{
    let test_result = await (client.request.invokeTemplate("connectionTest", { "context": { "ocSubdomain": ocSubdomain, "fdSubdomain": fdSubdomain, "ocSecretKey": ocSecretKey } }));
    console.log('checkSecretKey result arrived: ' + test_result.response);
    if ((test_result.status != 200) || (test_result.headers['content-type']!='application/json;charset=utf-8')){
      return 'No connection possible. Check your subdomain or try later.';
    }
    const response = JSON.parse(test_result.response);
    if (!response.onecockpit){
      return 'No OneCockpit installation detected.';
    }else{
      var errors = [];
      if (!response.active){
        errors.push('Your Freshdesk integration is set to inactive.');
      }
      if (!response.apikey_exists){
        errors.push('You need to enter your Freshdesk API key in your OneCockpit installation.');
      }
      if (!response.subdomain_exists){
        errors.push('You need to enter your Freshdesk subdomain in your OneCockpit installation.');
      }else if (!response.subdomain_matches){
        errors.push('Your Freshdesk subdomain does not match the one entered in your OneCockpit installation.');
      }
      if (!response.secret_key_exists){
        errors.push('You need to enter your Freshdesk secret key in your OneCockpit installation.');
      }else if (!response.secret_key_matches){
        errors.push('Your Freshdesk secret key does not match the one entered in your OneCockpit installation.');
      }
      if (errors.length > 0){
        let result = errors.join(' <br>');
        return result;
      }
    }
  }catch(err){
    return 'No connection possible now. Check your subdomain or try later.';
  }
  return '';
}

Hey @OneCockpit-Dev,
I see that a function checkSecretKey is used to make an API call. If you are using events in iparams.json file, can you share that or your iparams.html file?

Hello,
thank you for looking into this. The content of iparams.json is as follows:

  "ocSubdomain": {
    "display_name": "Subdomain",
    "description": "Please enter your OneCockpit subdomain",
    "type": "text",
    "regex": {
      "valid-subdomain": "^[A-Za-z0-9](?:[A-Za-z0-9\\-]{0,61}[A-Za-z0-9])?$",
      "valid-subdomain-error": "Character not allowed in subdomain"
    },
    "required": true,
    "events": [{
      "change": "checkSubdomain"
    }]
  },
  "ocSecretKey": {
    "display_name": "Secret Key",
    "description": "Please enter your OneCockpit secret key",
    "type": "text",
    "secure": true,
    "required": true,
    "events": [{
      "change": "checkSecretKey"
    }]
  },
  "fdSubdomain": {
    "display_name": "Freshdesk Subdomain",
    "description": "Usually, this should be autofilled and never changed",
    "type": "domain",
    "visible": true,
    "data-bind": "product.domain",
    "type_attributes": {
      "product": "freshdesk"
    },
    "required": true
  }  
}

Hi @OneCockpit-Dev,
For making requests via installation page, it is recommended you use iparams.html for custom iparams that also include the {{{appclient}}}.