Hidden Assumptions in solid-start

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

Every codebase relies on things it never checks. Most of them are routine. CodeSea looked at solidjs/solid-start 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

If Vite generates multiple entry points or fails to mark any chunk as entry, the build fails with cryptic error messages rather than gracefully handling multi-entry scenarios or providing clear debugging info

Worth your attention first

If the imported component exports something other than a JSX-returning function (like a class, object, or async function), clientOnly wrapper will fail at runtime during hydration with no type checking

Worth your attention first

If running in environments without location.port (some web workers) or behind proxies that strip port info, the fetch URL becomes malformed leading to network errors

Show everything (9 more)
Ordering

Client environment build must complete before SSR environment build, and both must finish before Nitro configuration is resolved

If this fails: If SSR build starts before client assets are available or Nitro tries to reference client chunks before they exist, the build process produces incorrect asset references or missing files

packages/start-nitro-v2-vite-plugin/src/index.ts:buildApp
Resource

Global ssrBundle and ssrEntryFile variables persist between generateBundle and buildApp phases without being overwritten by concurrent builds

If this fails: In parallel build scenarios or rapid dev rebuilds, race conditions cause wrong bundle data to be used, resulting in servers that reference non-existent entry points or stale code

packages/start-nitro-v2-vite-plugin/src/index.ts:ssrBundle
Domain

FileRoutes component scans a src/routes directory structure and automatically maps file paths to route patterns using filesystem conventions

If this fails: If src/routes doesn't exist, contains non-component files, or uses naming patterns that don't match FileRoutes expectations, routing silently fails with no pages accessible

apps/fixtures/basic/src/app.tsx:FileRoutes
Environment

MountableElement el exists in DOM and is empty or safe to replace when render() is called

If this fails: If el is null, already has event listeners, or contains form data, mount() either crashes with null reference or destroys user data without warning

packages/start/src/client/spa/index.tsx:mount
Temporal

Server function hello() can be called immediately during component initialization before SSR context is fully established

If this fails: If getRequestEvent() returns null during early SSR phases, the server function crashes with property access on undefined, breaking page rendering

apps/fixtures/experiments/src/routes/index.tsx:hello
Contract

All lazy-loaded components (Lazy, LazyGlob, LazyLink, etc.) export default functions that return valid JSX and don't throw during initialization

If this fails: If any lazy component has side effects, missing exports, or throws on import, the Suspense boundary shows loading state indefinitely while errors are silently swallowed

apps/fixtures/css/src/routes/index.tsx:lazy imports
Scale

Hard-coded compatibilityDate '2024-11-19' remains valid for Nitro's API contract and feature set across all deployment targets

If this fails: As Nitro evolves, this fixed date may trigger deprecated behavior warnings or break compatibility with newer deployment platforms that require updated compatibility settings

packages/start-nitro-v2-vite-plugin/src/index.ts:compatibilityDate
Environment

Import.meta.glob('../components/lazyG*.tsx') finds at least one file matching the glob pattern and Object.values()[0] is a valid module factory

If this fails: If no files match lazyG*.tsx pattern or directory structure changes, LazyGlob becomes undefined and crashes when lazy() tries to call it

apps/fixtures/css/src/routes/index.tsx:import.meta.glob
Domain

CSS files imported with ?url suffix return valid URLs that can be used in link rel='stylesheet' href attributes

If this fails: If build system doesn't handle ?url imports correctly or CSS files are missing, pages load with broken stylesheet links causing unstyled content flash

apps/fixtures/css/src/routes/index.tsx:CSS imports

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

Full analysis of solidjs/solid-start →

Frequently Asked Questions

What does solid-start assume that could break in production?

The one most likely to cause trouble: SSR bundle contains exactly one entry point with isEntry: true flag set by Vite, and no other chunks have isEntry: true If this fails, If Vite generates multiple entry points or fails to mark any chunk as entry, the build fails with cryptic error messages rather than gracefully handling multi-entry scenarios or providing clear debugging info

How many hidden assumptions does solid-start have?

CodeSea found 12 assumptions solid-start relies on but never validates, 4 of them critical, spanning Contract, Domain, Environment, Ordering, Resource, Temporal, 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.