I have a function that returns a render array for a table; private function _files_table($job_id){ $files = $this->_query(" select * from JC_Documents_Recent_Revisions where Job_ID=".$this->sqs($job_id)."; "); $rows = array_map(function($row){ return [ (string)$row['Job_ID'], $row['Document_Name'], $row['Document_Type'], $row['File_Name'], ($row['Uploaded_Date'] != NULL ? $row['Uploaded_Date']->format("Y-m-d H:i") : 'Unknown Date'), $row['Uploaded_By'], new FormattableMarkup('<a href=":link">show</a>', [':link' => (Url::fromRoute('JobFileUpload.Serve', ['file_id' => (int)$row['FileID']]))->toString()]), new FormattableMarkup('<a href=":link">revise</a>', [':link' => (Url::fromRoute('JobFileUpload.Revise', ['file_id' => (int)$row['FileID']]))->toString()]), new FormattableMarkup('<a href=":link">delete</a>', [':link' => (Url::fromRoute('JobFileUpload.Delete', ['document_id' => (int)$row['DocumentID']]))->toString()]) ]; }, $files); $header = [ t('Job ID'), t('Document Name'), t('Document Type'), t('File Name'), t('Uploaded Date'), t('Uploaded By'), t('Download'), t('Revise'), t('Delete') ]; return [ '#theme' => 'table', '#header' => $header, '#rows' => $rows ]; } and two occasions where I wish to render the table. The first is in `buildForm`: /** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state, $job_id=NULL) { $jobs = $this->_query(" select * from Active_Job_List; "); $formatted_jobs = []; $len = count($jobs); for($i=0; $i<$len; $i++){ $formatted_jobs[$jobs[$i]['Job_ID']] = $jobs[$i]['Job_Name']; } natsort($formatted_jobs); $form['job_id'] = [ '#weight' => 1, '#title' => t('Job'), '#type' => 'select', '#options' => $formatted_jobs, '#ajax' => [ 'callback' => '::showFiles', 'wrapper' => 'ajax-wrapper' ], '#required' => TRUE, '#default_value' => $job_id ]; $form['jobfiles'] = $this->_files_table($job_id); $form['jobfiles']['#weight'] = 2; if($job_id != null){ $form['newfile'] = [ '#weight' => 3, '#title' => t('Upload new file'), '#type' => 'link', '#url' => Url::fromRoute('JobFileUpload.UploadForm', ['job_id' => $job_id]) ]; } return $form; } The second is in showFiles: public function showFiles(array &$form, FormStateInterface $form_state) { $job_id = $form_state->getValue('job_id'); $output = $this->_files_table((int)$job_id); // $output['link'] = new FormattableMarkup('<a href=":link">Upload a new file...</a>', [':link' => (Url::fromRoute('JobFileUpload.UploadForm', ['job_id' => $job_id]))->toString()]); $renderer = \Drupal::service('renderer'); $response = new AjaxResponse(); $response->addCommand(new HtmlCommand('#ajax-wrapper', $renderer->render($output))); return $response; } The buildForm method works just fine, and I get a table with the files in it. But when I call the same render array function on an output for the AjaxResponse, I don't even get an error, and the table does not show up. Anyone got an idea of what I'm doing wrong here?