Hidden Assumptions in bokeh
10 assumptions this code never checks · 3 critical · spanning Domain, Shape, Environment, Resource, Scale, Temporal, Contract, Ordering
Every codebase relies on things it never checks. Most of them are routine. CodeSea looked at bokeh/bokeh 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 a data source contains a column with incompatible data (like objects that Array.from() creates weird arrays from), get_array returns T[] but with wrong element types, causing type-unsafe operations downstream in GlyphView rendering
If hit testing occurs before rendering completes, accessing this.index throws 'index_data() wasn't called', breaking selection and interaction features silently until user clicks
If multiple bokeh plots try to use different WebGL contexts, they share the same ReglWrapper instance tied to the first context, causing rendering artifacts or crashes when switching between plots
Show everything (7 more)
WebGL extensions ['ANGLE_instanced_arrays', 'EXT_blend_minmax', 'OES_element_index_uint'] will be available in the browser context, but only checks if WebGL context creation succeeds
If this fails: If any required extension is missing, regl initialization may fail or glyphs render incorrectly without clear error messages, causing fallback to Canvas2D without user awareness
bokehjs/src/lib/models/glyphs/webgl/regl_wrap.ts:constructor
Factor arrays will contain reasonable numbers of unique string values (hundreds, not millions), but no bounds checking exists on the factors parameter length
If this fails: With millions of categorical factors, the mapping creation becomes O(n²) in memory and extremely slow, potentially causing browser tabs to hang or crash during coordinate transformation
bokehjs/src/lib/models/ranges/factor_range.ts:map_one_level
Source files on disk won't change between dependency resolution and compilation phases, but no file locking or timestamp validation occurs
If this fails: If files are modified during the build process (common in watch mode), the compiler may use stale dependency graphs with fresh file contents, producing inconsistent builds or missing imports
bokehjs/src/compiler/build.ts:compiler host and file system operations
The SelectionManager will coordinate with GlyphRenderer views that have been properly initialized and connected through signals, but no validation ensures the renderer-datasource binding
If this fails: If a GlyphRenderer is created but not properly connected to its data source's selection signals, selection highlighting breaks—users can select points but visual feedback disappears, making multi-plot dashboards unusable
bokehjs/src/lib/models/sources/columnar_data_source.ts:selection_manager
connect_signals() will be called after constructor but before any property changes or event callbacks are triggered, following a strict initialization order
If this fails: If properties are modified before connect_signals() runs, the _update_property_callbacks() won't be set up, causing js_property_callbacks to silently fail and custom JavaScript event handlers to never execute
bokehjs/src/lib/model.ts:connect_signals lifecycle
Factor tuples will consistently have the same nesting level throughout a single dataset (all L1Factor, all L2Factor, or all L3Factor), but no runtime validation enforces homogeneity
If this fails: Mixing factor levels like [['A'], ['B', 'C']] causes coordinate mapping to fail unpredictably—some categorical points render in wrong positions or disappear entirely from plots
bokehjs/src/lib/models/ranges/factor_range.ts:FactorSeq type system
Input JSON from stdin or argv.file will conform to the expected schema with 'code', 'lang', 'file', and 'bokehjs_dir' fields, but only validates file existence not content structure
If this fails: Malformed compilation requests cause JSON.parse() to throw or compile_and_resolve_deps() to fail with cryptic errors, breaking bokeh server's dynamic extension loading without clear error messages
bokehjs/src/compiler/main.ts:compile function
See the full structural analysis of bokeh: the pipeline, data models, and system behavior that put these assumptions in context.
Full analysis of bokeh/bokeh →Frequently Asked Questions
What does bokeh assume that could break in production?
The one most likely to cause trouble: Column data retrieved by string key will either be null, an array, or something that Array.from() can convert (assumes it's array-like), but never validates the key exists in schema or that the converted data has the expected element type If this fails, If a data source contains a column with incompatible data (like objects that Array.from() creates weird arrays from), get_array returns T[] but with wrong element types, causing type-unsafe operations downstream in GlyphView rendering
How many hidden assumptions does bokeh have?
CodeSea found 10 assumptions bokeh relies on but never validates, 3 of them critical, spanning Domain, Shape, Environment, Resource, Scale, Temporal, Contract, Ordering. 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.