How to Debug Python in Excel
The fastest way to debug Python in Excel is to identify which boundary failed before changing code.
A Python-powered workbook spans several systems at once: worksheet values, workbook bindings, Python logic, package/runtime behavior, published outputs, Excel formulas, saved notebook state, and sometimes external services. A visible symptom can originate several layers away.
Use one sequence repeatedly:
Observe the symptom → identify the boundary → inspect the smallest state on each side → reproduce → fix → verify after reopen.
This article focuses on Boardflare Python for Excel and works through three common failure patterns. The maintained Troubleshooting and Reference page remains the source of truth for current error states and API details.
Start with the symptom, not the code
Use the visible failure to choose the first boundary to inspect.
| Symptom | First boundary to inspect |
|---|---|
| Notebook value does not change after editing Excel | Worksheet → bf.inputs() binding |
| Python result is numerically wrong | Validated input → model logic |
| Notebook looks correct but worksheet output is wrong | bf.publish() → BF.OUTPUT() |
BF.FUNCTION() does not resolve |
Published function → worksheet call |
| Import fails | Browser/WebAssembly package compatibility |
| Workbook works until closed | Session state → saved workbook state |
Workbook opens with #BUSY! indefinitely |
Runtime startup → publication registry |
Do not start by rewriting the model. First prove where correct state stops flowing.
Failure 1: Excel changed, but Python did not
Suppose a planner edits Inputs!A4:D20, but the notebook output does not change.
Start at the worksheet-to-Python boundary:
inputs = bf.inputs(
data=bf.ref("Inputs!A4:D20", headers=True),
threshold="Dashboard!B6",
)
inputs
inputs.errors
inputs["data"]
inputs["threshold"]Check four things in order:
- The worksheet value. Is the user editing the range the notebook actually references?
- The input widget. Does the displayed binding show the expected canonical reference and shape?
inputs.errors. Did the host reject or fail to materialize the binding?- The Python value. Does
inputs["data"]orinputs["threshold"]contain the changed state?
If the Python value is already wrong, do not debug downstream calculations yet.
A useful deliberate failure is to change the worksheet layout without updating the reference. If the binding now points at the wrong columns or headers, the notebook should expose that at the input boundary rather than letting you chase a later chart or solver error.
Once the value arrives correctly, validate it immediately:
if data.empty:
raise ValueError("Input table contains no rows.")
if data["Amount"].isna().any():
raise ValueError("Amount contains blank values.")
if not 0 <= threshold <= 1:
raise ValueError("Threshold must be between 0% and 100%.")Validation moves failures toward their cause. A blank workbook cell that silently becomes NaN is much harder to diagnose if it travels through several transformations before failing inside a solver or chart.
See Working with Excel for current input-reference behavior and type conversion.
Failure 3: it works now, but fails after reopen
A workbook that works in the author’s current session is not yet a reliable deliverable.
Session state can hide problems with unsaved notebook source, temporary Python objects, runtime startup, packages, or external services. The persistence test is therefore part of debugging, not a final cosmetic check.
Use this sequence:
- save until Boardflare reports the notebook as saved;
- close the workbook;
- reopen it in a fresh session;
- allow the Python runtime and publication registry to initialize;
- verify the worksheet outputs;
- change one representative workbook input;
- verify reactive recalculation;
- test the intended App/Edit presentation.
A brief #BUSY! during cold start is different from a workbook that never reaches publication. If #BUSY! persists, inspect runtime status, package/import failures, saved source loading, and whether execution reaches bf.publish().
This is also where author/operator testing matters. A workbook that only succeeds in the author’s warm session has not proved that another user can operate the saved application.
See App Mode and Sharing for the current save, reopen, and second-user boundary.
When the failure really is in the Python model
If workbook inputs are correct and publication is not involved yet, reduce the calculation to a known fixture.
Record:
- the exact input rows;
- the expected output;
- the relevant assumptions;
- the smallest function that should produce the result.
Then ask:
What is the earliest intermediate value that differs from the expected fixture?
In a reconciliation model, test candidate scoring separately from one-to-one assignment. In a forecast, test one model’s prediction separately from backtest aggregation. In an optimizer, inspect objective coefficients, constraints, and bounds before blaming the solver.
The maintained Boardflare templates use baseline and changed-input scenarios for the same reason: the workbook should prove that it recomputes from changed worksheet state rather than merely contain a correct static result.
Package failures belong at the browser/runtime boundary
Boardflare’s browser runtime is not the same environment as desktop Python. Pyodide is CPython compiled to WebAssembly for browsers, and package compatibility depends on what can run in that environment.
If an import works on a laptop but fails in the workbook:
- check transitive dependencies, not just the top-level import;
- distinguish pure-Python/Pyodide-compatible packages from packages that require unsupported native dependencies;
- verify the package against the browser/Pyodide runtime rather than assuming a desktop wheel will work.
A package failure is not fixed by changing workbook formulas. The notebook child also permanently sets connect-src 'self', so notebook code cannot call arbitrary external origins directly. Use a separate managed/external integration for workflows that require unrestricted network access.
The Security and Data Flow guide describes Boardflare’s current network-isolation boundary.
Force failures before users find them
Do not validate only the happy path. Deliberately trigger representative failures:
- blank a required input;
- enter an invalid threshold;
- change a worksheet shape expected by a binding;
- request an unknown published output;
- use a scenario that makes an optimization infeasible when that is possible;
- close and reopen from a cold start.
The question is not merely whether the workbook fails. It is whether the failure appears at the correct boundary and tells the operator what to do next.
A reusable debugging sequence
When a workbook fails, inspect these boundaries in order:
Excel value
↓
BF input binding
↓
validated Python value
↓
model/intermediate result
↓
published output/function
↓
Excel consumer
↓
save/reopen + second-user behavior
At each arrow, inspect one value or status on both sides. The first boundary where correct state becomes incorrect is the layer to fix.
For current symptoms and recovery actions, use Troubleshooting and Reference.