Hidden Assumptions in chatwoot
12 assumptions this code never checks · 5 critical · spanning Contract, Ordering, Environment, Shape, Temporal, Scale, Domain, Resource
Every codebase relies on things it never checks. Most of them are routine. CodeSea looked at chatwoot/chatwoot 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".
If server returns conversations with different schemas (missing properties, different structure), the merge operation will create conversations with undefined properties or overwrite important data, breaking real-time message display
If contact IDs are invalid, missing, or point to the same contact, ContactMergeAction will receive nil objects or attempt to merge a contact with itself, likely causing database constraint violations or data corruption
If database schema changes column names, API serialization changes field names, or internationalization affects attribute keys, contact filtering will silently fail to match any records
Show everything (9 more)
Assumes conversationsForADate array is already sorted by timestamp in ascending order for avatar display logic - compares current message with next message at index+1 to determine if sender changed
If this fails: If messages arrive out of order or array is not pre-sorted, avatar display logic will be incorrect, showing/hiding avatars at wrong positions and creating confusing conversation flows
app/javascript/widget/store/modules/conversation/helpers.js:groupConversationBySender
Assumes IndexedDB is available and functional, only checks for initialization failure but not for subsequent database corruption, quota exceeded, or browser security policies that disable IndexedDB
If this fails: Database operations after initialization can fail silently, causing cache reads to return empty arrays while cache keys indicate valid data exists, leading to unnecessary API calls and stale UI state
app/javascript/dashboard/api/CacheEnabledApiClient.js:getFromCache
Assumes cache keys from server API remain consistent between the initial cache_keys request and when cached data is actually used - no validation that cache hasn't been invalidated during the multi-step cache validation process
If this fails: Race condition where cache key validates as current but server data changes before cached data is returned, causing dashboard to display stale information until next cache refresh cycle
app/javascript/dashboard/api/CacheEnabledApiClient.js:validateCacheKey
City filter configuration has inconsistent dataType 'Number' (capitalized) while other location/text fields use 'text' or 'number' - assumes this dataType mismatch doesn't affect filter operator behavior or data validation
If this fails: City filters may not work correctly with text-based city names, causing type coercion errors or preventing users from filtering contacts by city location
app/javascript/dashboard/routes/dashboard/contacts/contactFilterItems/index.js:city
Assumes unlimited memory for storing all conversations in browser memory via allConversations array, with no upper limit or cleanup mechanism for long-running dashboard sessions
If this fails: In busy customer support environments, the conversation store will grow unbounded, eventually causing browser memory exhaustion, tab crashes, and degraded performance as conversation count increases
app/javascript/dashboard/store/modules/conversations/index.js:allConversations
Assumes authentication mechanism is mutually exclusive - if access token headers are present, user session authentication is bypassed entirely, with no validation that access token is actually valid before skipping session checks
If this fails: Malformed or invalid access tokens in headers will bypass session authentication, potentially allowing unauthenticated requests to proceed until validate_bot_access_token! is called, creating security gaps
app/controllers/api/base_controller.rb:authenticate_by_access_token?
Assumes label parameter is a single string value that can be safely URL-encoded with labels[]= format, but doesn't validate if label contains characters that break URL parameter parsing
If this fails: Contact labels containing special characters (=, &, %, spaces) will malform the query string, causing contact filtering by labels to return incorrect results or server parsing errors
app/javascript/dashboard/api/contacts.js:buildContactParams
Assumes system clock is accurate and Date.getTime() provides sufficient uniqueness for temporary message IDs when combined with getUuid(), but doesn't handle clock skew or rapid message creation scenarios
If this fails: If system clock jumps backward or multiple messages are created in rapid succession, timestamp-based logic for message ordering could fail, displaying messages out of sequence in widget conversations
app/javascript/widget/store/modules/conversation/helpers.js:createTemporaryMessage
Assumes store.dispatch('setUser') always resolves successfully and that getCurrentUser getter returns consistent user object structure with accounts array and account_id properties
If this fails: If user authentication fails or user object has unexpected structure, route navigation will redirect to wrong routes or cause JavaScript errors, potentially leaving users stuck on authentication pages
app/javascript/dashboard/routes/index.js:validateAuthenticateRoutePermission
See the full structural analysis of chatwoot: the pipeline, data models, and system behavior that put these assumptions in context.
Full analysis of chatwoot/chatwoot →Frequently Asked Questions
What does chatwoot assume that could break in production?
The one most likely to cause trouble: Assumes conversation objects have exactly the same schema when merging, specifically that both old and new conversations have 'allMessagesLoaded', 'messages', and 'dataFetched' properties that can be safely preserved from the existing conversation If this fails, If server returns conversations with different schemas (missing properties, different structure), the merge operation will create conversations with undefined properties or overwrite important data, breaking real-time message display
How many hidden assumptions does chatwoot have?
CodeSea found 12 assumptions chatwoot relies on but never validates, 5 of them critical, spanning Contract, Ordering, Environment, Shape, Temporal, Scale, Domain, Resource. 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.