{"slug": "that-gpt-4o-hallucination-that-invented-a-whole-asyncpg-api", "title": "That GPT-4o hallucination that invented a whole `asyncpg` API", "summary": "OpenAI's GPT-4o hallucinated a non-existent asyncpg API, inventing parameters like health_check_interval and health_check_query for create_pool() and a Pool.health_check() method, which caused TypeError and AttributeError in Python code. The model conflated real asyncpg features—max_inactive_connection_lifetime, acquire() timeout, and manual SELECT 1 checks—into a plausible but fictional interface, as documented in a developer's blog post. The incident highlights the risk of AI-generated code that appears coherent but is factually incorrect, requiring developers to verify against official documentation and source code.", "body_md": "# That GPT-4o hallucination that invented a whole `asyncpg` API\n\n## The prompt\n\n```\n# Asked GPT-4o for a production-ready asyncpg pool pattern\n# with proper lifecycle management and health checks\n```\n\n## What it gave me\n\n``` python\nimport asyncpg\nfrom contextlib import asynccontextmanager\n\nclass DatabasePool:\n    def __init__(self, dsn: str, min_size: int = 10, max_size: int = 50):\n        self.dsn = dsn\n        self.min_size = min_size\n        self.max_size = max_size\n        self._pool: asyncpg.Pool | None = None\n        self._health_check_task: asyncio.Task | None = None\n\n    async def initialize(self) -> None:\n        self._pool = await asyncpg.create_pool(\n            self.dsn,\n            min_size=self.min_size,\n            max_size=self.max_size,\n            command_timeout=60,\n            # These two parameters DO NOT EXIST in asyncpg 0.29.0\n            health_check_interval=30,\n            health_check_query=\"SELECT 1\",\n        )\n        self._health_check_task = asyncio.create_task(self._health_monitor())\n\n    @asynccontextmanager\n    async def acquire(self) -> AsyncGenerator[asyncpg.Connection, None]:\n        if self._pool is None:\n            raise RuntimeError(\"Pool not initialized\")\n        async with self._pool.acquire() as conn:\n            yield conn\n\n    async def _health_monitor(self) -> None:\n        while True:\n            await asyncio.sleep(30)\n            # This method DOES NOT EXIST\n            await self._pool.health_check()\n\n    async def close(self) -> None:\n        if self._health_check_task:\n            self._health_check_task.cancel()\n        if self._pool:\n            await self._pool.close()\n```\n\n## The error that sent me down the rabbit hole\n\n```\nTypeError: create_pool() got unexpected keyword arguments: \n    'health_check_interval', 'health_check_query'\nAttributeError: 'Pool' object has no attribute 'health_check'\n```\n\n## What I tried before realizing it was hallucinated\n\n1. **Checked asyncpg docs** — no `health_check_interval`\n\n, no `health_check_query`\n\n, no `Pool.health_check()`\n\n2. **Searched GitHub issues** — zero results for these parameters\n\n3. **Dug through source** — `create_pool`\n\nsignature only accepts: `dsn`\n\n, `min_size`\n\n, `max_size`\n\n, `command_timeout`\n\n, `timeout`\n\n, `loop`\n\n, `connection_class`\n\n, `init`\n\n, `setup`\n\n, `server_settings`\n\n, `statement_cache_size`\n\n, `max_queries`\n\n, `max_inactive_connection_lifetime`\n\n4. **Tested on 0.28.0, 0.29.0, 0.30.0** — same error every version\n\n## Where the hallucination likely came from\n\nThe model conflated three real things:\n\n| Real thing | What it does |\n\n|------------|--------------|\n\n| `max_inactive_connection_lifetime`\n\n(asyncpg 0.29+) | Closes idle connections after N seconds |\n\n| `asyncpg.Pool.acquire()`\n\ntimeout parameter | Fails fast if no connection available |\n\n| `asyncpg.Connection.execute(\"SELECT 1\")`\n\n| Manual health check pattern people actually use |\n\nIt then **invented a cohesive API** around these concepts that *looks* like it should exist — consistent naming, sensible defaults, proper async context manager usage. That's the dangerous part: it's not random garbage, it's *plausible* garbage.\n\n## The actual working pattern\n\n``` python\nimport asyncpg\nimport asyncio\nfrom contextlib import asynccontextmanager\n\nclass DatabasePool:\n    def __init__(self, dsn: str, min_size: int = 10, max_size: int = 50):\n        self.dsn = dsn\n        self.min_size = min_size\n        self.max_size = max_size\n        self._pool: asyncpg.Pool | None = None\n\n    async def initialize(self) -> None:\n        self._pool = await asyncpg.create_pool(\n            self.dsn,\n            min_size=self.min_size,\n            max_size=self.max_size,\n            command_timeout=60,\n            max_inactive_connection_lifetime=300,  # Real parameter\n        )\n\n    @asynccontextmanager\n    async def acquire(self) -> AsyncGenerator[asyncpg.Connection, None]:\n        if self._pool is None:\n            raise RuntimeError(\"Pool not initialized\")\n        async with self._pool.acquire(timeout=10) as conn:  # Real timeout\n            yield conn\n\n    async def health_check(self) -> bool:\n        \"\"\"Manual health check — call this from your /health endpoint\"\"\"\n        if self._pool is None:\n            return False\n        try:\n            async with self._pool.acquire(timeout=2) as conn:\n                await conn.execute(\"SELECT 1\")\n            return True\n        except Exception:\n            return False\n\n    async def close(self) -> None:\n        if self._pool:\n            await self._pool.close()\n```\n\n## The pattern I'm seeing\n\nHallucinations cluster around **plausible API extensions** — methods/parameters that *should* exist based on naming conventions and common patterns. The model isn't retrieving; it's *synthesizing* a consistent interface from partial knowledge.\n\nAnyone else hit this with asyncpg or other libraries? Wondering if there's a systematic way to catch these before they waste hours.\n\n[Next Greg Brockman's tightening grip on OpenAI has me nervous about →](/en/threads/7191/)\n\n[a library of Claude prompt techniques](https://tanyan888.com/), with plenty of directly applicable cases.", "url": "https://wpnews.pro/news/that-gpt-4o-hallucination-that-invented-a-whole-asyncpg-api", "canonical_source": "https://promptcube3.com/en/threads/7206/", "published_at": "2026-08-21 20:49:22+00:00", "updated_at": "2026-08-21 21:12:54.769364+00:00", "lang": "en", "topics": ["large-language-models", "generative-ai", "ai-safety"], "entities": ["OpenAI", "GPT-4o", "asyncpg"], "alternates": {"html": "https://wpnews.pro/news/that-gpt-4o-hallucination-that-invented-a-whole-asyncpg-api", "markdown": "https://wpnews.pro/news/that-gpt-4o-hallucination-that-invented-a-whole-asyncpg-api.md", "text": "https://wpnews.pro/news/that-gpt-4o-hallucination-that-invented-a-whole-asyncpg-api.txt", "jsonld": "https://wpnews.pro/news/that-gpt-4o-hallucination-that-invented-a-whole-asyncpg-api.jsonld"}}