Render error tracking your coding agent can read

Updated 2026-11-07

A web service on Render is a long-running process, and when it throws, the stack trace lands in the service's logs where nobody is watching. The Runheed SDK reports each exception with the commit Render deployed (RENDER_GIT_COMMIT) and keeps pull request previews apart from production. On a deploy, Render sends SIGTERM to the old instance and SIGKILL 30 seconds later unless you change the shutdown delay. The Node.js SDK batches events for up to 5 seconds, so the Node.js server below flushes on SIGTERM; the Python SDK sends each event before capture_exception returns. Your coding agent then reads the error and the stack trace over MCP.

Set it up

  1. 1.Install the SDK (Node.js or Python), and add RUNHEED_DSN under your service's Environment settings in the Render Dashboard.

    terminalbash
    npm install https://runheed.com/dl/runheed-0.1.5.tgz express
    # or, for Python:
    pip install https://runheed.com/dl/runheed-0.1.5-py3-none-any.whl fastapi uvicorn
  2. 2.Node.js with Express: initialize first, add the error handler after your routes, and flush on SIGTERM. Set the service's start command to node server.mjs.

    server.mjsjavascript
    import express from 'express';
    import runheed, { expressErrorHandler } from 'runheed';
    
    runheed.init({
      dsn: process.env.RUNHEED_DSN,
      // Render sets IS_PULL_REQUEST=true on pull request previews and RENDER_GIT_COMMIT on every deploy.
      environment: process.env.IS_PULL_REQUEST === 'true' ? 'preview' : 'production',
      release: process.env.RENDER_GIT_COMMIT,
    });
    
    const app = express();
    app.use(express.json());
    
    app.post('/api/checkout', async (req, res) => {
      const { cartId } = req.body;
      // ...your code
      res.json({ ok: true, cartId });
    });
    
    app.use(expressErrorHandler());
    
    const server = app.listen(process.env.PORT ?? 3000);
    
    // On a deploy Render sends SIGTERM, then SIGKILL after the shutdown delay (30 s by default).
    // The SDK batches events for up to 5 seconds: finish open requests, send the batch, then exit.
    process.on('SIGTERM', () => {
      server.close(async () => {
        await runheed.flush();
        process.exit(0);
      });
    });
  3. 3.Python with FastAPI: the SDK sends each event before capture_exception returns, so there is nothing to flush. Set the start command to uvicorn main:app --host 0.0.0.0 --port $PORT.

    main.pypython
    import os
    import runheed
    from fastapi import FastAPI
    from runheed import FastAPIIntegration
    
    runheed.init(
        dsn=os.environ["RUNHEED_DSN"],
        environment="preview" if os.environ.get("IS_PULL_REQUEST") == "true" else "production",
        release=os.environ.get("RENDER_GIT_COMMIT"),
    )
    
    app = FastAPI()
    integration = FastAPIIntegration()
    integration.setup(runheed.get_client())
    app.add_middleware(integration.create_middleware())
    
    @app.post("/api/checkout")
    async def checkout(body: dict):
        # ...your code
        return {"ok": True, "cart_id": body["cartId"]}
  4. 4.Deploy, then connect your agent with the server URL and a sign-in (Claude Code shown; Cursor, claude.ai and ChatGPT take the same URL).

    terminalbash
    claude mcp add --transport http runheed https://runheed.com/api/mcp

The npm and PyPI releases are not out yet, so these commands install the same package files straight from runheed.com. Nothing else changes when the registry versions ship.

What it catches

  • Errors thrown in Express routes and middleware, or raised in FastAPI routes, with the method, URL and the commit Render deployed
  • Uncaught exceptions and unhandled promise rejections in the Node.js process, and uncaught exceptions in Python
  • Pull request previews kept apart from production by environment (IS_PULL_REQUEST)
  • Errors you report yourself with captureException / capture_exception and any context you pass

What it does not do

  • A Node.js process killed with SIGKILL, after the shutdown delay or by running out of memory, loses events still waiting in the batch
  • Background workers and cron jobs are separate services: initialize the SDK there too and report from their own catch blocks
  • Django and Flask on Render use the hooks on their own setup pages
  • Browser errors are not captured; there is no browser SDK yet

Then ask your agent

> what broke in production since the last deploy? fix the top one and resolve it with the commit hash

Connect Runheed first: Claude Code, Cursor or another client. Then see how the agent fixes and resolves an error.

Common Render (Node.js and Python) errors

Plans from $29/moOther agents and editorsCancel any time from the billing portal