Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/operations/observability.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ Use the *raw* request body, not a re-serialized JSON object, since re-serializin

The webhook URL is validated with the same guard (`SSRF_GUARD`, private/loopback/metadata-address blocking) used for every other outbound call this app makes on a user's behalf, both when it's saved and again on every dispatch, and redirects are not followed. On AnythingMCP Cloud the URL must use `https`, and it ignores both the env (`SSRF_ALLOWED_HOSTS`) and the admin-editable SSRF allowlist, which name hosts only the platform may reach. On a self-hosted instance the operator's allowlist applies, so an internal Mattermost or Slack proxy can receive alerts.

## Fatal crash reports (always on in the Docker image)

A fatal V8 error, such as an out-of-memory abort, ends the backend before any JavaScript handler runs, so the log has no stack. `start.sh` therefore starts the backend with `--report-on-fatalerror`: on such a crash Node writes a diagnostic report (`report.<date>.<time>.<pid>...json`) with the native stack, heap spaces and resource usage, plus the JavaScript stack when V8 can still produce one. It goes to `HEAP_SNAPSHOT_DIR` (`/app/diagnostics` in the image, a volume on AnythingMCP Cloud), next to the heap snapshots. Environment variables are left out of the report (`--report-exclude-env`); a Node older than 22.13 cannot do that, so on such a build the report stays off. Self-hosted and Cloud behave the same; to keep the reports across container recreation on a self-hosted install, mount a volume at `/app/diagnostics`.

## Correlating across pipelines

The same `req.id` UUID appears in:
Expand Down
16 changes: 15 additions & 1 deletion start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,21 @@ run_migrations() {
# suits a ~4GB host. The backend's own heap guard (see
# packages/backend/src/common/process-vitals.ts) exits gracefully at a
# percentage of whatever this is, before V8 hits the wall.
BACKEND_CMD="node --max-old-space-size=${NODE_MAX_OLD_SPACE_MB:-2048} dist/src/main.js"
#
# A fatal V8 error (e.g. "Zone Allocation failed" on 13 Oct, with the heap at
# a third of its cap) kills the process before any JS handler runs, so the
# log shows no stack. --report-on-fatalerror writes a Node diagnostic report
# (native stack, heap spaces, resource usage, and the JS stack when V8 can
# still produce one) next to the heap snapshots; on Cloud that directory is a
# volume that outlives the restart. The report would include every
# environment variable, secrets too, so it is only switched on where Node can
# leave them out (--report-exclude-env, Node >= 22.13); an older Node, which
# would refuse to start on the unknown flag, runs without it.
REPORT_FLAGS=""
if node --report-exclude-env -e 0 >/dev/null 2>&1; then
REPORT_FLAGS="--report-on-fatalerror --report-exclude-env --report-compact --report-directory=${HEAP_SNAPSHOT_DIR:-/tmp}"
fi
BACKEND_CMD="node --max-old-space-size=${NODE_MAX_OLD_SPACE_MB:-2048} ${REPORT_FLAGS} dist/src/main.js"

case "$MODE" in
backend)
Expand Down
Loading