JavaScript TypeError in expandTextarea() when chatbot form fails to render
>>> [!note] Migrated issue <!-- Drupal.org comment --> <!-- Migrated from issue #3573134. --> Reported by: [scontzen](https://www.drupal.org/user/3838981) Related to !1192 >>> <p> <strong>Update Summary: </strong>Fix TypeError in expandTextarea() when chatbot form<br> element is missing<br> <strong>Short Description: </strong>Uncaught TypeError crashes chat toggle when AI<br> provider times out<br> <strong>Check-in Date: </strong>02/12/2026<br> <em>Metadata is used by the <a href="https://www.drupalstarforge.ai/" title="AI&lt;br /&gt; Tracker">AI Tracker.</a> Docs and additional fields <a href="https://www.drupal.org"></a> href="<a href="https://www.drupalstarforge.ai/ai-dashboard/docs">https://www.drupalstarforge.ai/ai-dashboard/docs</a>" title="AI Issue Tracker<br> Documentation"&gt;here.</em><br> [/Tracker]</p> <h3 id="summary-problem-motivation">Problem/Motivation</h3> <p> When the chatbot form fails to render (e.g. due to an API provider timeout or<br> unreachable endpoint), <code>form-stream.js</code> throws an uncaught<br> <code>TypeError</code> in the <code>expandTextarea()</code> function. This breaks all<br> subsequent JavaScript execution in the <code>$(document).ready()</code> handler &mdash;<br> including the chat minimize/maximize toggle functionality.</p> <p> The root cause is in <code>modules/ai_chatbot/js/form-stream.js</code>, line 255&ndash;261:</p> <p> <code>document.getElementById(id)</code> returns <code>null</code> when the form<br> element does not exist in the DOM. Calling <code>.addEventListener()</code> on<br> <code>null</code> throws the TypeError:</p> <pre> jQuery.Deferred exception: Cannot read properties of null (reading 'addEventListener') TypeError: Cannot read properties of null (reading 'addEventListener') at expandTextarea (form-stream.js:256:32) at HTMLDocument.<anonymous> (form-stream.js:238:5) </anonymous></pre><h4 id="summary-steps-reproduce">Steps to reproduce (required for bugs, but not<br> feature requests)</h4> <p> <strong>AI modules enabled:</strong> ai, ai_chatbot, ai_provider_openai<br> <strong>AI provider:</strong> OpenAI (via Guzzle HTTP)<br> <strong>Browser:</strong> Any (tested in Chrome)</p> <p> 1. Configure the AI Chatbot block with an AI provider (e.g. OpenAI)<br> 2. Trigger a scenario where the provider is unreachable or times out (e.g. network<br> issue, invalid API key, Guzzle timeout exceeding 30s)<br> 3. Load a page that displays the chatbot block<br> 4. Open the browser console<br> 5. Observe the TypeError &mdash; the chatbot header renders but clicking it does not toggle<br> the chat window open/closed</p> <h3 id="summary-proposed-resolution">Proposed resolution</h3> <p> Add a null check in <code>expandTextarea()</code> before attaching the event listener:</p> <pre> function expandTextarea(id) { var el = document.getElementById(id); if (el) { el.addEventListener('keyup', function () { this.style.overflow = 'hidden'; this.style.height = 0; this.style.height = this.scrollHeight + 'px'; }, false); } } </pre><h3 id="summary-remaining-tasks">Remaining tasks</h3> <p> - Review and merge the proposed fix</p> <h3>Optional: Other details as applicable (e.g., User interface changes, API changes,<br> Data model changes)</h3> <p> No UI, API, or data model changes. This is a defensive null check only.</p> <h3 id="summary-ai-usage">AI usage (if applicable)</h3> <p> [x] AI Assisted Issue<br> This issue was generated with AI assistance, but was reviewed and refined by the<br> creator.</p> <p> [] AI Assisted Code<br> This code was mainly generated by a human, with AI autocompleting or parts AI<br> generated, but under full human supervision.</p> <p> [ ] AI Generated Code<br> This code was mainly generated by an AI with human guidance, and reviewed, tested, and<br> refined by a human.</p> <p> [ ] Vibe Coded<br> This code was generated by an AI and has only been functionally tested.</p>
issue