Hidden Assumptions in uptime-kuma

12 assumptions this code never checks · 4 critical · spanning Resource, Contract, Ordering, Temporal, Scale, Environment, Domain, Shape

Every codebase relies on things it never checks. Most of them are routine. CodeSea looked at louislam/uptime-kuma and picked out the few most likely to cause trouble. The full list is just below.

Most of what this code assumes is routine. These 3 are the ones most likely to cause trouble here. The rest are minor; they're under "Show everything".

Worth your attention first

Under high load with many setting reads, cache grows unbounded until 60-second cleanup, potentially causing memory exhaustion in containers with strict memory limits

Worth your attention first

If a custom MonitorType sets heartbeat.status to undefined or returns instead of throwing on failure, the monitor appears stuck in PENDING state and notifications never trigger

Worth your attention first

Database migrations may apply in wrong order causing foreign key constraint failures or missing columns when patches depend on each other

Show everything (9 more)
Temporal

Assumes monitor intervals in monitorList are properly cleaned up when monitors are deleted - no explicit cleanup code visible for stopping intervals

If this fails: Deleted monitors continue executing their check intervals indefinitely, consuming CPU and potentially hitting rate limits on monitored services

server/uptime-kuma-server.js:monitorList
Scale

Assumes notification providers can handle unlimited concurrent sends without rate limiting - each monitor status change triggers immediate notification.send()

If this fails: When many monitors fail simultaneously (network outage), notification providers like Discord/Slack get flooded with requests and return 429 rate limit errors, causing notification delivery failures

server/notification-providers/notification-provider.js:NotificationProvider.send
Environment

Assumes WebSocket origin validation with 'cors-like' mode works correctly across all deployment scenarios - defaults to 'cors-like' if unset

If this fails: In reverse proxy setups or Docker containers, WebSocket connections may be rejected due to origin mismatch, breaking real-time dashboard updates without clear error messages

server/server.js:process.env.UPTIME_KUMA_WS_ORIGIN_CHECK
Domain

Assumes monitorJSON['type'] field always contains valid monitor type strings matching the hardcoded cases (push, ping, port, dns, etc)

If this fails: If database contains monitors with unknown or corrupted type values, extractAddress returns empty string, causing notification messages to show blank addresses for affected monitors

server/notification-providers/notification-provider.js:extractAddress
Shape

Assumes all setting values can be safely JSON.stringify()'d without circular references or functions

If this fails: Setting values containing circular objects or functions cause JSON.stringify to throw, leaving the setting in inconsistent state and potentially breaking system configuration

server/settings.js:Settings.set
Resource

Assumes build environment has sufficient disk space for both gzip and brotli compressed assets during production builds

If this fails: In CI/CD environments with limited disk space, build fails silently when compression plugins run out of space writing compressed assets to tmp directory

config/vite.config.js:viteCompression
Contract

Assumes the underlying apicache module honors headerBlacklist configuration and the cache-control override works correctly

If this fails: The comment 'BUG! Not working for the second request' indicates cache-control header override fails intermittently, causing client-side caching when server-side only caching was intended

server/modules/apicache/index.js:headerBlacklist
Domain

Assumes push monitor endpoints accept status, msg, and ping parameters via query string in that exact format

If this fails: If push monitor API changes parameter format or requires different encoding, example scripts fail silently or send malformed data that registers as DOWN status

extra/push-examples/javascript-fetch/index.js:pushURL
Environment

Assumes FreeBSD hostname configuration differs from other Unix systems and should not read HOST environment variable

If this fails: On FreeBSD systems, server ignores HOST environment variable even when it contains valid configuration, potentially binding to unexpected interfaces

server/config.js:isFreeBSD

See the full structural analysis of uptime-kuma: the pipeline, data models, and system behavior that put these assumptions in context.

Full analysis of louislam/uptime-kuma →

Frequently Asked Questions

What does uptime-kuma assume that could break in production?

The one most likely to cause trouble: Assumes cache cleaner interval runs indefinitely without memory pressure checks - Settings.cacheCleaner interval never stops once started and accumulates cache entries If this fails, Under high load with many setting reads, cache grows unbounded until 60-second cleanup, potentially causing memory exhaustion in containers with strict memory limits

How many hidden assumptions does uptime-kuma have?

CodeSea found 12 assumptions uptime-kuma relies on but never validates, 4 of them critical, spanning Resource, Contract, Ordering, Temporal, Scale, Environment, Domain, Shape. Most are routine — the analysis flags the two or three most likely to actually bite.

What is a hidden assumption?

Something the code depends on but never checks: a data shape, an ordering, an environment condition, a scale limit, or a contract with another service. It holds until the world it runs in changes, then fails silently.