Can an AJAX form request replace elements of different types?
I should try using #prefix/#suffix for wrapper instead the element itself. Also IMHO it's not a good idea mess around with the elements you send during build. Take in mind the the build is done every time you render the form, even for AJAX calls. A possible solution could be hide the second element using Form States API and put the Please make selection in your prior element.

public function buildForm(array $form, FormStateInterface $form_state) {
  // Code excerpt.
  $form['job_id'] = [
    '#weight' =&gt; 1,
    '#title' =&gt; t('Job'),
    '#type' =&gt; 'select',
    '#empty_value' =&gt; t('Please select a job'),
    '#options' =&gt; $formatted_jobs,
    '#ajax' =&gt; [
      'callback' =&gt; [get_class($this), 'showFiles'],
      'wrapper' =&gt; 'ajax-wrapper',
      'event' =&gt; 'change',
    ],
    '#required' =&gt; TRUE,
  ];

  // Render a hidden and empty list.
  $form['jobfiles'] = [
    '#weight' =&gt; 2,
    '#title' =&gt; t('Files'),
    '#type' =&gt; 'item_list',
    '#items' =&gt; [],
    '#prefix' =&gt; '&lt;div id="ajax-wrapper"&gt;',
    '#suffix' =&gt; '&lt;/div&gt;',
    '#attributes' =&gt; [
      'class' =&gt; ['invisible']
    ]
  ];

  return $form;
}

public function showFiles(array &amp;$form, FormStateInterface $form_state) {
  $job_id = $form_state-&gt;getValue('job_id');
  $form['jobfiles']['#items'] = $this-&gt;_files((int)$job_id);
  // Remove the 'invisible' class.
  $form['jobfiles']['#attributes']['class'] = array_filter($form['jobfiles']['#attributes']['class'], function($v) {
    return $v != 'invisible';
  });
  // You could also return the element instead.
  $response = new AjaxResponse();
  $response-&gt;addCommand(new ReplaceCommand('#ajax-wrapper', [$form['jobfiles']]));

  return $response;
}


Hope this may help you.

Update:
Replace $element with $form. Also worth checking the answer provided by @joshua-moore as it is valid too.