Skip to main content

CrashMin

Failure-preserving HTTP request reduction.

Paste a grotesque Chrome Copy as cURL. Say what “still broken” means. Get back a tiny request that still reproduces your failure.

CrashMin reducing an anonymized Chrome Copy as cURL from 12,441 bytes to 117 bytes

12,441 bytes   →   117 bytes
1,053 pieces   →   6
99.06% smaller
same panic     →   YES (20/20)
curl -H 'x-crash-token: letmein' \
  -d '{"payload":{"deeply":{"nested":{"trigger":"boom"}}}}' \
  'http://127.0.0.1:18765/a'

That GIF is the product. Everything else is how to run it.

This is not a formatter and not a “make the response look the same” minimizer.

Other tools ask CrashMin asks
Is the response still identical? Is it still broken the way I said?

License: MIT.


A real Chrome copy (anonymized)

corpus/repros/anonymized-chrome-saas.curl is a Chrome 128 DevTools → Copy as cURL (bash) of a workspace-settings save:

  • lowercase header names, priority, sec-ch-ua, --data-raw
  • next-auth / Stripe / Intercom / GA cookie names
  • 24 members, feature flags, activity log

Hosts, bearer, emails, and IDs were replaced before it entered git. Replay is loopback-only so the crash is deterministic. How it was scrubbed: corpus/ANONYMIZATION.md.

Bytes What remains
Chrome copy, as pasted 12,441 17 cookies, UTMs, 24 members, flags, activity
Header/cookie/query deletion only 11,069 almost the entire JSON body
CrashMin 117 one header + payload.deeply.nested.trigger

Header strippers cannot see a nested JSON field. That leftover ~11 KB is the wedge.

python3 -m crashmin.fixtures --port 18765 &
python3 -m crashmin corpus/repros/anonymized-chrome-saas.curl \
  --status 500 \
  --body-regex 'panic: nil pointer' \
  --final-confirm 20 \
  --compact

Or the packaged walkthrough: bash scripts/demo.sh.

Install

Python 3.10+, no runtime dependencies.

pip install git+https://github.com/robbyczgw-cla/crashmin.git
pip install .   # from a clone
crashmin --help

For coding agents

Unix CLI. No MCP, no SDK, no daemon.

crashmin req.curl --status 500 --body-regex 'panic' --json --quiet -o min.curl

--json writes one object to stdout (schema: 1). crashmin --schema prints the schema. Exit 0 means use .minimized.curl. Anything else, read .error_code.

Contract: docs/agents.md · AGENTS.md

Safety — read this

CrashMin sends the request many times. It will mutate whatever you point it at.

  • Default: loopback only. Anything else is refused.
  • Use a local or staging target. Never production.
  • --allow-remote means you accept the blast radius.
  • Use --confirm N on flaky or non-idempotent endpoints.
  • A Copy as cURL is a session dump. Do not commit one, do not paste one into an issue.

docs/safety.md · docs/privacy.md.

Usage

crashmin request.curl --status 500 --body-regex 'panic: nil pointer'
crashmin request.http --status '>=500'
crashmin capture.har  --body-contains 'INTERNAL ERROR'
crashmin request.curl --oracle ./interesting.sh --confirm 5

Input is auto-detected: curl …, raw HTTP, or HAR (first entry, or --har-index N).

Minimized request → stdout. Scoreboard → stderr.

crashmin req.curl --status 500 > min.curl

Oracles (AND-combined; at least one required)

Flag Interesting when
--status 500 / '>=500' / 5xx status matches
--body-contains TEXT body contains the literal
--body-regex REGEX body matches
--header NAME=VALUE response header matches
--timeout-is-failure the client timed out
--oracle SCRIPT script exits 0

--confirm N — keep a candidate only if it fails N/N times. --final-confirm N — re-send the answer N times and print same failure: YES (N/N).

Full contract: docs/oracles.md.

What it shrinks

HTTP structure, top-down — never raw bytes:

headers → cookies → query → form fields → nested JSON → primitives → path (carefully)

Host and Content-Length are rebuilt on the way out.

v0.1 does not shrink multipart or mystery content types.

When this is worth it

Worth it when the crash lives in JSON shape and the paste is huge.

Not worth it when the bug is “needs Authorization” — delete that header by hand, or use curlmin.

corpus/REPORT.md · docs/competition.md

Not this project

Not a Burp/Postman replacement, proxy, scanner, fuzzer, dashboard, or cloud service. A reducer.

Library

from crashmin.detect import parse_input
from crashmin.executor import Executor
from crashmin.oracle import compile_oracle
from crashmin.reduce import reduce_request

req = parse_input(open("request.curl").read())
oracle = compile_oracle(statuses=["500"], body_regexes=[r"panic: nil pointer"])
result = reduce_request(req, Executor(oracle=oracle, confirm=5))
print("\n".join(result.summary_lines()))

Develop

pip install -e '.[dev]'
pytest -q
python scripts/bench.py        # benchmarks/report.md
python scripts/corpus.py       # corpus/REPORT.md
python scripts/record_demo.py  # docs/demo.gif (needs Pillow + ffmpeg)

Toy crash servers: python3 -m crashmin.fixtures --port 18765 (POST /a/e, GET /f).

License

MIT. Use it, fork it, vendor it. Keep the copyright notice.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

crashmin-0.1.0.tar.gz (47.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

crashmin-0.1.0-py3-none-any.whl (44.0 kB view details)

Uploaded Python 3

File details

Details for the file crashmin-0.1.0.tar.gz.

File metadata

  • Download URL: crashmin-0.1.0.tar.gz
  • Upload date:
  • Size: 47.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for crashmin-0.1.0.tar.gz
Algorithm Hash digest
SHA256 1044e95d3d7b588012ab33119cd13018a1e242505c862dc8961e53fa1550a9e0
MD5 9fe75791c466b2ae771d2458458b2726
BLAKE2b-256 a99fb9dcb624ae316e67c73d93efc5493068c6253c7908ce2c86f73e61fa01d2

See more details on using hashes here.

File details

Details for the file crashmin-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: crashmin-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 44.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for crashmin-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4f26f57b7bb39397132f6d7d5d2a71d8e8b7f601426c1d9c9f91c5d5566f1e73
MD5 a0a1013aeb7eba2ce590eb9ae2a3ed1a
BLAKE2b-256 34afec233ed684674f21c09ea98864aacd27f9159d36716717ec1c8149cc3f0a

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page