Why did my benchmark stop at N=22? A debugging story in…
    Neura MarketNeura Market/CoPilot
    ChatGPTChatGPTClaudeClaudeGeminiGeminiCursorCursorGrokGrokPerplexityPerplexityCoPilotCoPilot
    DeepSeekDeepSeekStable DiffusionStable DiffusionMidjourneyMidjourney
    View All Directories
    OverviewRulesPromptsMCPsAgentsGamesBlogVideosGuidesCoursesCommunityPluginsTrending
    CoPilotBlogWhy did my benchmark stop at N=22? A debugging story in nine bugs
    Back to Blog
    Why did my benchmark stop at N=22? A debugging story in nine bugs
    bugsmash

    Why did my benchmark stop at N=22? A debugging story in nine bugs

    xbill July 15, 2026
    0 views

    Submission for DEV's Summer Bug Smash — Smash Stories track. There was a file in my repo called...


    title: "Why did my benchmark stop at N=22? A debugging story in nine bugs" published: true series: Bugs tags: bugsmash, debugging, ai, python

    Submission for DEV's Summer Bug Smash — Smash Stories track.

    There was a file in my repo called run_benchmark_1_22.py.

    Not 1 to 24, which is what the harness was written to do. Not 1 to 26, which is how many Mersenne exponents the agents know. Twenty-two. A chart in the README — a2a_latency_times_1_22.png — agreed. At some point, past-me had decided the benchmark ends at 22, committed the evidence, and moved on.

    This summer, hunting for a Bug Smash target, I finally asked: why 22?

    The setup

    a2a-benchmark compares A2A agent performance across four languages. Python and Go sit behind Gemini tool-calling (ADK); Node and Rust are bare HTTP handlers. Each computes Mersenne primes with Lucas–Lehmer; a harness sweeps N from 1 to 24 and draws two charts.

    I ran the full sweep. At N=24, the Python column printed N/A. Every other language returned data. There it was — not a decision, a crash, worked around by shortening the run until it stopped hurting.

    The old chart: the benchmark's world ended at N=22

    The 4,300-digit wall

    The Python agent's response at N=24 wasn't even subtle about it:

    "Exceeds the limit (4300 digits) for integer string conversion;
     use sys.set_int_max_str_digits() to increase the limit"
    

    CPython 3.11 added a default cap on int→str conversion — 4,300 digits — as a denial-of-service mitigation. My agent stringified every prime it found. The 24th Mersenne prime, 2^19937−1, has 6,002 digits.

    Here's the part that made me laugh out loud: the stringified list was never returned. The tool reports only its elapsed time. The line that had silently amputated my benchmark at N=23 was decorative. The fix was git rm energy: delete the str(), keep the raw int. Go had the identical dead weight (val.String()) inside its timed region — it just happened not to crash.

    One deleted expression, and a column of data that had never existed came into being: N=24, Python, 2,425.9 ms.

    It gets worse before it gets better

    With the agents finally running, I kept pulling the thread. The harness parsed Python's elapsed time out of the LLM's prose with r"It took ([\d\.\-e]+) seconds". Gemini, in my captures, never once said "It took" — it said "Calculating the first 5 Mersenne primes took…" and later "The calculation took…". The only reason the benchmark had Python data at all was a fallback that read the structured tool artifact. My measurement pipeline's primary path was a bet on a language model's phrasing habits.

    The direct agents had their own tells. Ask Node or Rust for 100 Mersenne primes and they'd cheerfully report "Found first 100 Mersenne primes" — having computed 26, the size of their exponent table. And they formatted elapsed time as %.2f ms, so Rust's fastest runs reported 0.00ms, which parses to zero, which cannot exist on a log-scale chart. Those points didn't look wrong; they looked like nothing.

    And the biggest lie was the chart itself: "A2A Round-Trip Time (including LLM/Tool calling)". Only half true — literally. Two of the four agents route through Gemini; two never touch an LLM. Median RTT: 2.6ms and 4.6ms for the direct pair, ~1.6s and ~1.8s for the Gemini pair. A ~400× gap presented as a language comparison was actually a pipeline comparison.

    The encores

    I fixed everything and re-ran the sweep to generate the "after" charts. Go's N=1 datapoint: N/A.

    Cause: my fix. With the dead formatting deleted, Go's small-N runs got so fast that time.Duration switched output units — Elapsed time: 836ns — and the harness parser had branches for µs, ms, and s, but had never met a nanosecond. The fix made the code too fast for its own benchmark.

    After: direct vs Gemini-brokered series, finally labeled as what they are

    Parser patched. Re-ran again. Three Go datapoints missing — different ones. The captured response text:

    "I already did that. Do you want to do it again?"

    The harness reused deterministic context IDs; ADK keeps per-context session history; on a rerun, Gemini looked at the old conversation and declined to redo the work. My benchmark's completeness now depended on a language model's opinions about repetition. Unique per-run IDs fixed it, and the final sweep came back 96/96.

    What I actually learned

    1. The workaround you commit is the bug you keep. run_benchmark_1_22.py sat in the repo like a fossil of an uninvestigated crash. The moment you rename the script instead of reading the stack trace, you've decided to ship the bug.
    2. Benchmarks are production code. Mine crashed, lied about counts, rounded away its smallest measurements, and compared two different architectures on one axis. Every chart it ever produced was quietly wrong in four ways.
    3. If a machine consumes the output, never route it through prose. Structured tool artifacts existed the whole time; the regex on LLM text was pure fragility.
    4. An LLM in the measurement path adds failure modes that have nothing to do with the code under test — including, apparently, boredom.

    Nine bugs. Four PRs (#1, #2, #3, #4). One question I should have asked a year ago: why 22?

    Don't take my word for any of it — docker run --rm -e GEMINI_API_KEY=your_key -v "$PWD/out:/out" xbill9/bugsmash runs all four fixed agents and the full sweep, and writes the charts to ./out.

    Disclosure: I ran this investigation with Claude Code as the debugging agent — it did the reproduction, the fixes, and the benchmark reruns while I steered. The bugs, the numbers, and the "I already did that" refusal are all real and archived in the repo.

    Tags

    bugsmashdebuggingaipython

    Comments

    More Blog

    View all
    Five Gemma-4 models, one accelerator: what porting E2B 31B to AWS Inferentia2 taught megemma

    Five Gemma-4 models, one accelerator: what porting E2B 31B to AWS Inferentia2 taught me

    I ported the whole Gemma-4 family — E2B, E4B, 12B, 31B, and the 26B-A4B MoE — to run on...

    X
    xbill
    Hey DEV, I'm Tobore. Let's actually connect.community

    Hey DEV, I'm Tobore. Let's actually connect.

    Hey DEV, I'm Tobore. Let's actually connect. I've been on here for a while now, mostly writing and...

    L
    Laurina Ayarah
    I burned through thousands of AI tokens. Then a friend did it for freeai

    I burned through thousands of AI tokens. Then a friend did it for free

    (yep, kinda clickbait, just for the funsies 😊) At the beginning of the year, I relaunched my...

    P
    Paulo Henrique
    Claude might be saturating your machineai

    Claude might be saturating your machine

    My laptop was sitting idle with the fan at full tilt. Nothing was running that I knew of. The culprit...

    S
    Sidhant Panda
    Automated GitHub Code Reviews Using Google Geminigithubactions

    Automated GitHub Code Reviews Using Google Gemini

    I Built a Thing! TL;DR — Google Gemini-based Pull Request reviews and Issue Triaging for...

    D
    Darren "Dazbo" Lester
    What is an "agentic harness," actually?ai

    What is an "agentic harness," actually?

    I've been hearing the word "harness" thrown around a lot lately. I assumed it just meant "the IDE" or...

    T
    Tilde A. Thurium

    Stay up to date

    Get the latest CoPilot prompts, rules, and resources delivered to your inbox weekly.

    Neura Market LogoNeura Market

    Discover the best AI prompts, plugins, and resources for CoPilot and more.

    Content Types

    • Rules
    • Prompts
    • MCPs
    • Agents
    • Guides

    Platforms

    • ChatGPT Directory
    • Claude Directory
    • Gemini Directory
    • Cursor Directory
    • Grok Directory
    • Perplexity Directory
    • DeepSeek Directory
    • CoPilot Directory
    • Stable Diffusion Directory
    • Midjourney Directory
    • All Directories

    Resources

    • Blog
    • Documentation
    • Help Center
    • Marketplace

    Legal

    • Privacy Policy
    • Terms of Service

    © 2026 Neura Market. All rights reserved.

    |

    Not affiliated with any AI platform vendors.

    Neura Market

    Custom AI Systems & Services

    Our team of experienced AI builders will help build custom AI systems, workflows, and solutions for your business.

    Request custom work

    Ready-made automations for this

    Workflows from the Neura Market marketplace related to this CoPilot resource

    • Create Emotional Stories with Gemini AI: Generate Images and Video JSON Promptsn8n · $24.99 · Related topic
    • Create Animated Stories Using GP-4.0-mini, Midjourney, Kling, and Creatomate APIn8n · $24.99 · Related topic
    • Interactive n8n Tutorial: Master Data Flow, Execution, and Debuggingn8n · $19.99 · Related topic
    • Automate LinkedIn Profile Discovery and Outreach via Form Submissionn8n · $14.99 · Related topic
    Browse all workflows