Problem
Some notebook environments execute cells based on a dependency graph rather than document order. For example, in marimo notebooks:
Cell 1: x = y + 1 # LSP reports F821: 'y' undefined
Cell 2: y = 10 # Actually executes first due to dependency graph
LSP servers analyzing notebooks assume top-to-bottom execution, causing false positives when the actual execution order differs from document order.
Proposal
Add an analysisOrder field to NotebookCell:
export interface NotebookCell {
kind: NotebookCellKind;
document: DocumentUri;
metadata?: LSPObject;
executionSummary?: ExecutionSummary;
/**
* Optional ordering hint for static analysis.
* When present, language servers SHOULD sort cells by this value
* (ascending) before analyzing. Cells without this field are
* analyzed after ordered cells, in document order.
*
* This allows notebook clients to communicate non-linear execution
* semantics to language servers for more accurate diagnostics.
*/
analysisOrder?: uinteger;
}
Example:
{
"cells": [
{ "document": "cell:1", "analysisOrder": 2 },
{ "document": "cell:2", "analysisOrder": 1 }
]
}
Cell 2 is analyzed first, so y is defined before cell 1 references it.
Alternatives
executionSummary.executionOrder
The existing executionOrder field could be used for this, but we want diagnostics before running any cells. Relying on executionOrder means:
- No ordering until the notebook is executed
- Resetting the notebook loses the order
- Clients need workarounds like creating fake executions just to maintain state
In VS Code, executionSummary is readonly on NotebookCell - the only way to set it is through NotebookCellExecution:
const execution = controller.createNotebookCellExecution(cell);
execution.executionOrder = order;
execution.start();
execution.end(true); // immediately end
This is awkward because it requires a NotebookController, shows execution UI feedback, and signals "this cell ran" when it hasn't.
analysisOrder should be something any LSP can set and manage independently.
metadata field
For today, we'll likely start implementing this in marimo-lsp using the metadata field and try to get buy-in from language servers:
{
"cells": [
{ "document": "cell:1", "metadata": { "analysisOrder": 2 } },
{ "document": "cell:2", "metadata": { "analysisOrder": 1 } }
]
}
A first-class field would signal that this is a supported protocol feature and give servers a clear contract to implement.
Use cases
- Reactive notebooks (marimo, Observable)
- Dependency-ordered execution environments
- Any notebook where static analysis order should differ from document order
Related
Problem
Some notebook environments execute cells based on a dependency graph rather than document order. For example, in marimo notebooks:
LSP servers analyzing notebooks assume top-to-bottom execution, causing false positives when the actual execution order differs from document order.
Proposal
Add an
analysisOrderfield toNotebookCell:Example:
{ "cells": [ { "document": "cell:1", "analysisOrder": 2 }, { "document": "cell:2", "analysisOrder": 1 } ] }Cell 2 is analyzed first, so
yis defined before cell 1 references it.Alternatives
executionSummary.executionOrderThe existing
executionOrderfield could be used for this, but we want diagnostics before running any cells. Relying onexecutionOrdermeans:In VS Code,
executionSummaryis readonly onNotebookCell- the only way to set it is throughNotebookCellExecution:This is awkward because it requires a
NotebookController, shows execution UI feedback, and signals "this cell ran" when it hasn't.analysisOrdershould be something any LSP can set and manage independently.metadatafieldFor today, we'll likely start implementing this in marimo-lsp using the
metadatafield and try to get buy-in from language servers:{ "cells": [ { "document": "cell:1", "metadata": { "analysisOrder": 2 } }, { "document": "cell:2", "metadata": { "analysisOrder": 1 } } ] }A first-class field would signal that this is a supported protocol feature and give servers a clear contract to implement.
Use cases
Related
marimo-lsp - currently works around this with complex middleware
Discussion welcome on naming (
analysisOrdervsstaticOrdervs something else)Global objects not recognized if defined in a subsequent cell of a Jupyter notebook pylance-release#4185
Disable B018 rule for Marimo notebooks? astral-sh/ruff#21301
ty not working with Marimo's VSCode extension astral-sh/ty#2100
Notebook support astral-sh/ty#173
imports are not respected by the linter across cells marimo-team/marimo-lsp#236
Add notebook cell ordering middleware for Ruff marimo-team/marimo-lsp#337
Use ty's native notebook support marimo-team/marimo-lsp#344