Home

Python

Streamlit error tracking with BugTape

pip install bugtape hooks Streamlit page errors, redacts by pattern, and groups repeats. Connect MCP so an agent can open a pull request a human reviews.

pip install bugtape reports Streamlit page errors from the Python process. Messages are redacted by pattern. Repeats group into one issue. You can then connect MCP so an agent opens a pull request a human reviews.

The full reference is Python. This page is the Streamlit path. A checklist post is Python and Streamlit ERROR logs.

Why Streamlit page errors are awkward

Streamlit catches page errors and shows them in the app. They do not reach Python's normal uncaught-exception hook. People have described the friction of forwarding those errors to Sentry on the Streamlit forum and in sentry-python issue 3017. Streamlit also documents st.App(on_script_error=…) when you want to write the handler yourself.

BugTape wraps the function Streamlit calls for those errors when Streamlit is imported. The app still shows the error. BugTape files one report with the page name and the Streamlit session, and it skips Streamlit's duplicate log of the same error.

If you already run Sentry, keep it. BugTape vs Sentry.

Install and start

pip install bugtape

The package on PyPI has no dependencies and supports Python 3.9 and later. The same reviewed wheel is pip install https://app.bugtape.ai/sdk/python/bugtape-0.1.1-py3-none-any.whl.

import streamlit as st
import bugtape

bugtape.init(service="analytics")

st.title("Revenue")

Set BUGTAPE_KEY to a capture key from Setup → Python (bt_live_… or bt_test_…). Without a key, init logs one warning and reporting stays off. Streamlit reruns the page on each interaction. A second init with the same settings keeps the running client.

If a future Streamlit release moves that hook, init(streamlit=True) logs a warning. You can wrap the page yourself:

from bugtape.integrations.streamlit import capture

with capture():
    render_page()

Check delivery with the one-liner from the docs:

BUGTAPE_KEY=bt_test_… python -c "import bugtape; bugtape.init(service='check'); bugtape.capture_message('BugTape Python check'); bugtape.flush()"

What leaves the server

SentNever sent
Exception type and a redacted messageFrame locals
File, function and line of each frameSource lines
service, release, environmentArguments passed to a log call
The log template, such as export failed for %sRequest bodies

Redaction covers quoted values, numbers, emails, SQL, and ids. An f-string such as ValueError(f"no rate for client {name}") is finished text before BugTape sees it, so the name can remain. For that code, pass log arguments, add extra_redactions, use before_send, or set send_messages=False. The patterns are in Python.

Server reports have no browser DOM replay. DOM replay is a browser SDK feature, and it is not a screen video.

Release, so a fix can be checked

Pass release, or set BUGTAPE_RELEASE or DD_VERSION. If those are empty, the SDK reads the first set CI commit variable, including GITHUB_SHA and VERCEL_GIT_COMMIT_SHA. The full list is bugtape.COMMIT_ENV_KEYS in the Python doc. A report with no release is stored as release_missing, and the release check cannot anchor.

Datadog, if you already have it

When ddtrace is already running, the report carries the active trace and span ids. BugTape does not start Datadog. Use BugTape with Datadog · Keep Datadog, add the agent loop.

Hand the issue to an agent

BugTape is not an APM product and it is not LLM observability, even when the Streamlit app calls a model. After the first error is in the inbox, connect MCP:

Start free and open Setup → Python. Where the data lives, and what redaction does not promise, is on Trust.

Your team reviews the PR. Agents do not silent-ship.