Hidden Assumptions in novel
12 assumptions this code never checks · 3 critical · spanning Domain, Shape, Contract, Environment, Ordering, Scale, Temporal
Every codebase relies on things it never checks. Most of them are routine. CodeSea looked at steven-tey/novel 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 the API route is missing, renamed, or returns different response format, image uploads fail silently or with cryptic errors - the promise resolves with the File object instead of URL, breaking image display
If MarkdownExtension isn't configured or storage structure changes, getPrevText() crashes with 'Cannot read property serialize of undefined', breaking AI completion context generation
Malformed File objects or files without proper MIME types bypass validation, potentially uploading non-images or oversized files that crash the upload endpoint
Show everything (9 more)
A DOM element with id 'slash-command' exists in the document when navigation keys are pressed during command mode
If this fails: If the command component unmounts or ID changes, keyboard navigation (ArrowUp, ArrowDown, Enter) fails silently - users can't navigate the command palette with keyboard
packages/headless/src/components/editor-command.tsx:onKeyDown
Image preloading completes before the promise resolves, ensuring the image is ready for display when URL is returned
If this fails: If image.onload never fires (network issues, invalid URLs, CORS problems), the upload promise never resolves, leaving UI in loading state indefinitely
apps/web/components/tailwind/image-upload.ts:image.onload
20MB is a reasonable file size limit that won't exceed server memory or request size limits
If this fails: If the server has smaller limits (default Next.js is 1MB), uploads that pass client validation will fail server-side with unclear error messages
apps/web/components/tailwind/image-upload.ts:validateFn
HTTP status codes have specific meanings: 200 = success with URL, 401 = missing blob token, anything else = unknown error
If this fails: If the API returns different status codes (403, 413, 500) or uses 200 for error states, the error handling logic misclassifies failures and shows wrong error messages
apps/web/components/tailwind/image-upload.ts:res.status
The tunnel instance from EditorCommandTunnelContext always has an Out component that can render without props
If this fails: If tunnel-rat library changes API or context is not properly initialized, rendering fails with 'Cannot read property Out of undefined'
packages/headless/src/components/editor-command.tsx:EditorCommandOut
The document object and addEventListener are available (browser environment) and keyboard events can be prevented and re-dispatched
If this fails: In server-side rendering or non-browser environments, document is undefined causing crashes during component mount
packages/headless/src/components/editor-command.tsx:navigationKeys
Strings containing dots but no spaces are likely URLs that can be prefixed with 'https://' to become valid URLs
If this fails: False positives like 'file.txt' or 'user.name' get converted to invalid HTTPS URLs, while valid URLs with spaces get rejected
packages/headless/src/utils/index.ts:getUrlFromString
Successful upload responses (status 200) always contain JSON with a 'url' string field
If this fails: If API returns different JSON structure or non-JSON response, destructuring fails with 'Cannot destructure property url of undefined'
apps/web/components/tailwind/image-upload.ts:res.json()
The ProseMirror document structure remains stable - editor.state.doc has a forEach method that calls callback with (node, pos) signature
If this fails: If Tiptap/ProseMirror changes document API, getPrevText fails with method not found errors
packages/headless/src/utils/index.ts:editor.state.doc.forEach
See the full structural analysis of novel: the pipeline, data models, and system behavior that put these assumptions in context.
Full analysis of steven-tey/novel →Frequently Asked Questions
What does novel assume that could break in production?
The one most likely to cause trouble: The /api/upload endpoint exists and accepts POST requests with file body and specific headers (content-type, x-vercel-filename), returning JSON with 'url' field on success If this fails, If the API route is missing, renamed, or returns different response format, image uploads fail silently or with cryptic errors - the promise resolves with the File object instead of URL, breaking image display
How many hidden assumptions does novel have?
CodeSea found 12 assumptions novel relies on but never validates, 3 of them critical, spanning Domain, Shape, Contract, Environment, Ordering, Scale, Temporal. 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.