<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: shekhar chandran</title>
    <description>The latest articles on DEV Community by shekhar chandran (@aiinsider).</description>
    <link>https://dev.to/aiinsider</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4122254%2Fbf9efa9e-ed29-4fa5-addd-6799cdd8f224.png</url>
      <title>DEV Community: shekhar chandran</title>
      <link>https://dev.to/aiinsider</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aiinsider"/>
    <language>en</language>
    <item>
      <title>OpenAI Just Opened Up Its Agents API — Here's What It Actually Means</title>
      <dc:creator>shekhar chandran</dc:creator>
      <pubDate>Tue, 15 Sep 2026 13:19:55 +0000</pubDate>
      <link>https://dev.to/aiinsider/openai-just-opened-up-its-agents-api-heres-what-it-actually-means-43k4</link>
      <guid>https://dev.to/aiinsider/openai-just-opened-up-its-agents-api-heres-what-it-actually-means-43k4</guid>
      <description>&lt;p&gt;OpenAI moved its Agents API into public beta this week. This is the same managed agent infrastructure that's been quietly powering Codex, now available for any developer to build on directly instead of just watching it work behind someone else's product.&lt;/p&gt;

&lt;p&gt;That's a bigger shift than it sounds. Up to now, "agent that can actually complete multi-step tasks" has mostly meant a research demo or a closed product. Packaging that as an API developers can call means the infrastructure war for "who runs your agents" is now as competitive as the model war was back in 2024 — and DeepSeek didn't wait long to respond, shipping its own leaner V4.1-Flash model with a smaller KV cache days later.&lt;/p&gt;

&lt;p&gt;If you're building with agents right now, this is worth watching closely — the tooling layer is moving as fast as the models themselves.&lt;/p&gt;

&lt;p&gt;I covered this alongside the rest of the week's bigger AI stories, including a pretty blunt safety statement from inside Anthropic.&lt;/p&gt;

&lt;p&gt;Full breakdown here: &lt;a href="https://aiinsider.in/ai-updates/ai-news-this-week-openai-and-anthropic-call-to-slow-down-deepseek-v4-1-flash-gemini-comes-to-windows-september-13-2026/" rel="noopener noreferrer"&gt;AI News This Week on AIInsider.in&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>programming</category>
    </item>
    <item>
      <title>My Copy Buttons Vanished on Production. The Bug Was Three WordPress Layers Deep</title>
      <dc:creator>shekhar chandran</dc:creator>
      <pubDate>Sat, 12 Sep 2026 14:59:00 +0000</pubDate>
      <link>https://dev.to/aiinsider/my-copy-buttons-vanished-on-production-the-bug-was-three-wordpress-layers-deep-203j</link>
      <guid>https://dev.to/aiinsider/my-copy-buttons-vanished-on-production-the-bug-was-three-wordpress-layers-deep-203j</guid>
      <description>&lt;p&gt;I shipped a small feature: 49 "📋 Copy Prompt" buttons on a prompt-library page, each with an inline &lt;code&gt;onclick&lt;/code&gt; that copies text to the clipboard. Worked perfectly in preview. Went live. Every single button vanished.&lt;/p&gt;

&lt;p&gt;Not broken — &lt;em&gt;gone&lt;/em&gt;. Not in the DOM. Not in "view source." Just... not there.&lt;/p&gt;

&lt;p&gt;Here's how I traced it through three separate, unrelated bugs stacked on top of each other, and what I learned about WordPress content filters and caching layers that I wish I'd known before shipping.&lt;/p&gt;

&lt;h2&gt;
  
  
  Symptom #1: things were also just... centered wrong
&lt;/h2&gt;

&lt;p&gt;Before I even got to the missing buttons, screenshots came in showing paragraphs and prompt boxes that should've been left-aligned rendering centered or oddly indented on certain line wraps. That one turned out to be simple: several wrapper divs and &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt;/&lt;code&gt;&amp;lt;h4&amp;gt;&lt;/code&gt; styles had no explicit &lt;code&gt;text-align&lt;/code&gt;, and something in the theme/page-builder CSS cascade was centering them under specific conditions. Fix: add explicit &lt;code&gt;text-align:left&lt;/code&gt; inline styles everywhere it mattered. Not interesting on its own — but it meant I almost stopped looking once I fixed the "obvious" visual bug, instead of noticing the buttons were missing entirely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Symptom #2: the buttons weren't just styled wrong, they didn't exist
&lt;/h2&gt;

&lt;p&gt;This is the one that took real digging. My working theory list, in order of how wrong each one was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cache serving stale content → ruled out (forced no-cache fetch, same result)&lt;/li&gt;
&lt;li&gt;CSS &lt;code&gt;display:none&lt;/code&gt; somewhere → ruled out (not in computed styles, because the elements weren't in the DOM at all)&lt;/li&gt;
&lt;li&gt;A plugin stripping &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; tags → seemed unlikely but worth checking&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The technique that actually cracked it was comparing the &lt;strong&gt;same content at three different layers&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;What's stored in the database&lt;/strong&gt; — clean, correct HTML, buttons present, &lt;code&gt;onclick&lt;/code&gt; intact.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What's actually served over HTTP&lt;/strong&gt; — fetched the live URL directly (bypassing any client-side rendering) and diffed it against #1.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What the browser's DOM ends up with&lt;/strong&gt; — &lt;code&gt;document.querySelectorAll('button')&lt;/code&gt; in devtools.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Layer 1 was fine. Layer 2 was corrupted. That narrowed it to something between "database" and "the HTTP response" — i.e., a content filter running at render time, not anything client-side.&lt;/p&gt;

&lt;h2&gt;
  
  
  Root cause: WordPress's own &lt;code&gt;wptexturize()&lt;/code&gt; was corrupting my HTML attributes
&lt;/h2&gt;

&lt;p&gt;WordPress runs &lt;code&gt;wptexturize()&lt;/code&gt; on &lt;code&gt;the_content&lt;/code&gt; at render time — it's the filter that turns straight quotes into "smart" curly quotes for readability in plain prose. The problem: it doesn't know the difference between quote characters in your visible text and quote characters inside an HTML attribute.&lt;/p&gt;

&lt;p&gt;My button markup looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;"navigator.clipboard.writeText('...');this.textContent='✓ Copied';"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  📋 Copy Prompt
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;wptexturize()&lt;/code&gt; converted some of the straight &lt;code&gt;'&lt;/code&gt; characters inside that &lt;code&gt;onclick&lt;/code&gt; string into curly-quote HTML entities (&lt;code&gt;&amp;amp;#8217;&lt;/code&gt;). That meant the &lt;em&gt;served&lt;/em&gt; HTML had no real closing quote for the attribute value anymore. The browser's HTML parser, following spec, treated the &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; tag as an attribute that never terminated — and silently swallowed everything after it into that one unclosed tag, until the next literal &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; string in the markup forced it closed. 49 buttons, cascading into each other, all eaten by the parser. That's why they weren't just mis-styled — they'd never actually existed as separate elements in the parsed DOM at all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; never put inline &lt;code&gt;onXXX="..."&lt;/code&gt; attributes with string literals containing quote characters into WordPress post/page content. I replaced all 49 buttons with a plain class and moved the behavior into one delegated listener:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"copy-btn"&lt;/span&gt; &lt;span class="na"&gt;data-text=&lt;/span&gt;&lt;span class="s"&gt;"the actual prompt text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  📋 Copy Prompt
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;data-no-optimize=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt; &lt;span class="na"&gt;data-cfasync=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.copy-btn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;btn&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clipboard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;✓ Copied&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Bug #3: the fix... also didn't work at first
&lt;/h2&gt;

&lt;p&gt;Buttons were back in the DOM. Great. Except the click handler still didn't fire. Same three-layer trick: DB content had the &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; block, but the served HTML didn't.&lt;/p&gt;

&lt;p&gt;This time it wasn't &lt;code&gt;wptexturize&lt;/code&gt; — it was LiteSpeed Cache's JS minify/combine optimizer silently stripping the inline &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; block during minification. Confirmed via response headers: &lt;code&gt;x-litespeed-cache: miss&lt;/code&gt; on a forced fresh render (so it wasn't a stale-cache problem) but &lt;code&gt;x-litespeed-tag&lt;/code&gt; showed an active JS-minify hash — meaning the optimizer was actively processing and dropping the block, not just caching it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; LiteSpeed Cache respects a documented exclusion convention — add &lt;code&gt;data-no-optimize="1" data-cfasync="false"&lt;/code&gt; to any inline &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; you need untouched (already in the snippet above). Script showed up in the served HTML immediately after that, and the click handler worked.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways if you're shipping anything similar on WordPress + LiteSpeed
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Never use inline &lt;code&gt;onXXX&lt;/code&gt; attributes with quoted string literals in post/page content.&lt;/strong&gt; &lt;code&gt;wptexturize()&lt;/code&gt; runs on &lt;code&gt;the_content&lt;/code&gt; and can corrupt quote characters inside them without warning — it only cares about "readable prose," not your JS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prefer &lt;code&gt;class&lt;/code&gt; + a single delegated event listener&lt;/strong&gt; over per-element inline handlers. Cleaner, and immune to the above.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Any inline &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; in post content on a LiteSpeed-cached WordPress site needs &lt;code&gt;data-no-optimize="1"&lt;/code&gt;&lt;/strong&gt;, or the JS minifier can silently strip it — no error, no warning, it's just gone from the served page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When something works in the database/editor but not live, diff three layers&lt;/strong&gt;: stored content → raw served HTTP response → parsed DOM. Whichever layer first shows the corruption tells you exactly which system to blame, instead of guessing across the whole stack.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fixing the obvious visual bug can make you stop looking too early.&lt;/strong&gt; The centering issue was real, but it wasn't the actual story — always check for a second, quieter bug hiding behind the loud one.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I ran into this while rebuilding a prompt-library page over on &lt;a href="https://aiinsider.in/ai-prompts/" rel="noopener noreferrer"&gt;AIInsider.in&lt;/a&gt; — if you're curious what the finished (bug-free) version looks like, that's it in the wild.&lt;/p&gt;

&lt;p&gt;Has anyone else been bitten by &lt;code&gt;wptexturize&lt;/code&gt; mangling inline JS? Curious how common this actually is outside my one site.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>ai</category>
      <category>webdev</category>
      <category>debugging</category>
    </item>
  </channel>
</rss>
