Hidden Assumptions in strapi
13 assumptions this code never checks · 4 critical · spanning Domain, Shape, Contract, Ordering, Temporal, Resource, Environment, Scale
Every codebase relies on things it never checks. Most of them are routine. CodeSea looked at strapi/strapi 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 production deployment uses localhost (like Docker containers or local staging), cloud plugin gets incorrectly enabled. If development uses custom domains, plugin gets incorrectly disabled.
Invalid email addresses get passed directly to Mailgun API, causing API errors or silent delivery failures instead of early validation errors
If plopfile exports different structure (named exports, class, object), generator execution fails with cryptic 'not a function' errors
Show everything (10 more)
Actions in ctx.state.actions array can be executed sequentially without dependencies - each action.build(ctx) call is independent
If this fails: If actions have dependencies (e.g., content type must exist before fixtures), build() executes them in registration order which may cause 'model not found' or constraint violation errors
packages/utils/api-tests/builder/index.js:build
The nodeSES client callback (err) => {} is always called exactly once per sendEmail call
If this fails: If AWS SES client hangs, times out, or calls callback multiple times, Promise never resolves/rejects or resolves/rejects multiple times causing memory leaks or duplicate processing
packages/providers/email-amazon-ses/src/index.ts:send
Translation files exist at ./translations/${locale}.json for all locales in app.locales array, and dynamic imports won't exceed module loading limits
If this fails: Missing translation files fail silently (catch returns empty data), but excessive locales could hit Node.js module cache limits or cause memory pressure during parallel imports
packages/plugins/cloud/admin/src/index.ts:registerTrads
Current working directory (process.cwd()) is writable and the join(dir, 'src') path structure exists or can be created by the template system
If this fails: If running in read-only filesystem or restricted permissions, template generation fails with EACCES errors. If 'src' directory structure doesn't match template expectations, files get created in unexpected locations
packages/generators/generators/src/index.ts:generate
strapi.getModel(modelsUtils.toContentTypeUID(modelName)) always returns a valid model object that strapi.contentAPI.sanitize.output can process
If this fails: If modelName doesn't correspond to registered content type or toContentTypeUID transforms incorrectly, getModel returns undefined causing sanitize.output to throw TypeError
packages/utils/api-tests/builder/index.js:sanitizedFixturesFor
The 'h:Reply-To' header format is the correct Mailgun API syntax and replyTo email addresses are valid RFC 5322 format
If this fails: If Mailgun changes header syntax or receives malformed reply-to addresses, emails send without reply-to functionality or get rejected by recipient servers
packages/providers/email-mailgun/src/index.ts:init
Default regex pattern '^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$' covers all valid color formats the application needs - assumes only hex colors
If this fails: Users cannot input valid CSS colors like 'rgb(255,0,0)', 'hsl(0,100%,50%)', or named colors like 'red', causing validation errors for legitimate color values
packages/plugins/color-picker/admin/src/index.ts:register
StrapiAppPlugin objects have register() and registerTrads() functions that accept 'app' parameter with specific methods like addMenuLink, registerPlugin
If this fails: If plugin doesn't implement expected interface or app object lacks required methods, admin panel initialization fails with 'undefined is not a function' errors during plugin loading
packages/core/admin/admin/src/index.ts:StrapiAppPlugin
Environment variable APP_KEYS contains properly formatted array strings that can be parsed by env.array() - assumes consistent deployment configuration
If this fails: If APP_KEYS is malformed or missing in production, falls back to development keys 'toBeModified1', 'toBeModified2' which compromises security of signed cookies and sessions
examples/complex/config/server.ts:serverConfig
Test data cleanup can be safely performed after tests complete - assumes no concurrent test execution or shared database state
If this fails: If tests run in parallel or share database instances, cleanup may delete data from running tests causing intermittent test failures or data corruption
packages/utils/api-tests/builder/index.js:cleanup
See the full structural analysis of strapi: the pipeline, data models, and system behavior that put these assumptions in context.
Full analysis of strapi/strapi →Compare strapi
Frequently Asked Questions
What does strapi assume that could break in production?
The one most likely to cause trouble: Development environment is determined solely by checking if backendURL contains 'localhost' - assumes localhost always means development and production never uses localhost If this fails, If production deployment uses localhost (like Docker containers or local staging), cloud plugin gets incorrectly enabled. If development uses custom domains, plugin gets incorrectly disabled.
How many hidden assumptions does strapi have?
CodeSea found 13 assumptions strapi relies on but never validates, 4 of them critical, spanning Domain, Shape, Contract, Ordering, Temporal, Resource, Environment, Scale. 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.