<?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: Agshin Rajabov</title>
    <description>The latest articles on DEV Community by Agshin Rajabov (@emotixco).</description>
    <link>https://dev.to/emotixco</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3803682%2Fb1c9590b-8c5c-48c9-b298-58fa3d635867.png</url>
      <title>DEV Community: Agshin Rajabov</title>
      <link>https://dev.to/emotixco</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/emotixco"/>
    <language>en</language>
    <item>
      <title>12 Claude Code Skills for Startup Founders [open-source]</title>
      <dc:creator>Agshin Rajabov</dc:creator>
      <pubDate>Tue, 10 Mar 2026 18:20:03 +0000</pubDate>
      <link>https://dev.to/emotixco/12-claude-code-skills-for-startup-founders-open-source-4lib</link>
      <guid>https://dev.to/emotixco/12-claude-code-skills-for-startup-founders-open-source-4lib</guid>
      <description>&lt;p&gt;Every Claude Code skills pack is built for developers. Code review, git workflows, security audits.&lt;/p&gt;

&lt;p&gt;Nothing for the founder who needs to validate an idea at 2am.&lt;/p&gt;

&lt;p&gt;We fixed that.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;claude-skills-founder&lt;/strong&gt; — 12 slash commands for startup strategy, running directly in Claude Code.&lt;/p&gt;

&lt;p&gt;No npm install. No dependencies. Just copy markdown files into your &lt;code&gt;.claude/commands/&lt;/code&gt; folder.&lt;/p&gt;

&lt;h2&gt;
  
  
  The skills
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Validation &amp;amp; Research:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/validate-idea&lt;/code&gt; — 7-dimension scorecard with build/pivot/kill verdict&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/product-brief&lt;/code&gt; — structured brief from a one-sentence idea&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/competitor-matrix&lt;/code&gt; — feature comparison + positioning gaps&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/persona-gen&lt;/code&gt; — 3 personas with priority matrix&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/user-interviews&lt;/code&gt; — Mom Test interview script + analysis framework&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Strategy &amp;amp; Growth:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/mvp-scope&lt;/code&gt; — ruthless feature triage (Must Have / Should Have / Won't Have)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/pricing-strategy&lt;/code&gt; — 6 models evaluated, 3 tiers designed, unit economics checked&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/go-to-market&lt;/code&gt; — pre-launch → launch day → 90-day plan&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/landing-page&lt;/code&gt; — conversion copy for every section&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/email-sequence&lt;/code&gt; — 5-7 onboarding emails, ready to send&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Fundraising &amp;amp; Metrics:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/pitch-deck&lt;/code&gt; — 12-slide outline with content per slide&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/fundraise-prep&lt;/code&gt; — readiness scorecard + investor targeting + 12-week timeline&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/metrics-dashboard&lt;/code&gt; — 5 metrics that matter at your stage&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
bash
# Install (30 seconds)
git clone https://github.com/emotixco/claude-skills-founder.git /tmp/csf
cp -r /tmp/csf/commands/ .claude/commands/founder/
rm -rf /tmp/csf

# Use
&amp;gt; /founder:validate-idea An AI tool that helps remote teams run async standups
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>claude</category>
      <category>startup</category>
      <category>opensource</category>
      <category>ai</category>
    </item>
    <item>
      <title>We spent a week debugging Gemini API in production. Here's what we found.</title>
      <dc:creator>Agshin Rajabov</dc:creator>
      <pubDate>Tue, 03 Mar 2026 10:57:05 +0000</pubDate>
      <link>https://dev.to/emotixco/we-spent-a-week-debugging-gemini-api-in-production-heres-what-we-found-45ch</link>
      <guid>https://dev.to/emotixco/we-spent-a-week-debugging-gemini-api-in-production-heres-what-we-found-45ch</guid>
      <description>&lt;p&gt;We've been running Google Gemini inside a multi-agent research pipeline at Emotix for a few months. It's fast, cheap, and surprisingly capable — but production exposed three reliability issues that cost us real debugging time. This is what we found and how we fixed it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Problem 1: MALFORMED_FUNCTION_CALL
&lt;/h2&gt;

&lt;p&gt;This one hurt the most.&lt;/p&gt;

&lt;p&gt;Gemini's &lt;code&gt;FunctionCallingMode.ANY&lt;/code&gt; is supposed to guarantee a tool call. It doesn't. When tool arguments contain large strings — typically 1000+ characters — Gemini returns &lt;code&gt;finishReason: MALFORMED_FUNCTION_CALL&lt;/code&gt; with no output. No error message, no partial result. Just silence.&lt;/p&gt;

&lt;p&gt;We dug into Google's issue tracker and found it's a confirmed P2 bug:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/googleapis/python-genai/issues/1120" rel="noopener noreferrer"&gt;python-genai#1120&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/googleapis/google-cloud-java/issues/11782" rel="noopener noreferrer"&gt;google-cloud-java#11782&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Still open. No ETA.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix 1 — Prompt instruction (~90% reduction)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Adding this to the prompt before every tool call cuts the error dramatically:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Ensure all string values in function call arguments are properly JSON-escaped (newlines as \n, quotes as \", backslashes as \)."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We tested this over 500+ production calls. It's not perfect but it handles the vast majority of cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix 2 — Structured output fallback (100% elimination)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When function calling still fails after retries, switch to &lt;code&gt;responseMimeType: 'application/json'&lt;/code&gt; + &lt;code&gt;responseSchema&lt;/code&gt;. This bypasses the function-calling code path entirely. No MALFORMED possible.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Instead of function calling:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateContent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;generationConfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;responseMimeType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;responseSchema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;yourToolSchema&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tradeoff: you lose the structured function-call interface and parse the JSON yourself. Worth it for reliability.&lt;/p&gt;




&lt;h2&gt;
  
  
  Problem 2: 429s with no backoff
&lt;/h2&gt;

&lt;p&gt;The free tier is 10 RPM. The SDK throws on 429 but gives you nothing to work with — no retry logic, no backoff, no way to know how backed up the queue is.&lt;/p&gt;

&lt;p&gt;We built an adaptive token-bucket rate limiter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GeminiRateLimiter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gemini-heal&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;limiter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GeminiRateLimiter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;rpm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Before every Gemini call:&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;limiter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;acquire&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// When you get a 429:&lt;/span&gt;
&lt;span class="nx"&gt;limiter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reportRateLimit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Circuit breaker — skip Gemini when queue is too deep:&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;limiter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shouldSkip&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// fall back to another model&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It automatically halves RPM on each 429 (floor: 2 RPM) and recovers by +2 RPM every 60 seconds of clean traffic. The &lt;code&gt;shouldSkip()&lt;/code&gt; circuit breaker lets you route to a fallback model instead of waiting.&lt;/p&gt;




&lt;h2&gt;
  
  
  Problem 3: JSON wrapped in markdown blocks
&lt;/h2&gt;

&lt;p&gt;This one is small but annoying. Even with &lt;code&gt;responseMimeType: 'application/json'&lt;/code&gt;, Gemini sometimes returns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;instead of plain JSON. It breaks &lt;code&gt;JSON.parse&lt;/code&gt; silently if you don't handle it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;stripMarkdownCodeBlock&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gemini-heal&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;stripMarkdownCodeBlock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;geminiResponse&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clean&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  We open-sourced the fixes
&lt;/h2&gt;

&lt;p&gt;After patching these issues across multiple services we extracted everything into a library called &lt;strong&gt;gemini-heal&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;gemini-heal @google/generative-ai
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GeminiRateLimiter&lt;/code&gt; — adaptive token-bucket with circuit breaker&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GeminiClient&lt;/code&gt; — completion wrapper with rate limiting and cost tracking&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ToolCaller&lt;/code&gt; — forced tool calling with MALFORMED retry + structured output fallback&lt;/li&gt;
&lt;li&gt;Utility helpers for 429 detection and markdown stripping&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Zero dependencies. TypeScript. MIT license.&lt;/p&gt;

&lt;p&gt;→ GitHub: &lt;a href="https://github.com/emotixco/gemini-heal" rel="noopener noreferrer"&gt;https://github.com/emotixco/gemini-heal&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're running Gemini in production and hitting any of these, hope it saves you some time. And if you've found other Gemini quirks worth handling, open an issue — we'd like to keep adding to it.&lt;/p&gt;

</description>
      <category>gemini</category>
      <category>typescript</category>
      <category>node</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
