Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions news/changelog-1.10.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ All changes included in 1.10:

- ([#14297](https://github.com/quarto-dev/quarto-cli/pull/14297)): Fix `quarto.utils.is_empty_node()` returning inverted results for text nodes (`Str`, `Code`, `RawInline`).

## Engines

### Jupyter

- ([#14374](https://github.com/quarto-dev/quarto-cli/pull/14374)): Avoid a crash when a third-party Jupyter kernel (observed with Maple 2025, built on XEUS) returns `execute_reply` without the required `status` field. The failing cell is recorded as an error instead of aborting the render. (author: @ChrisJefferson)

## Other fixes and improvements

- ([#6651](https://github.com/quarto-dev/quarto-cli/issues/6651)): Fix dart-sass compilation failing in enterprise environments where `.bat` files are blocked by group policy.
Expand Down
41 changes: 32 additions & 9 deletions src/resources/jupyter/notebook.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,9 +380,18 @@ def handle_meta_object(obj):
if cleanup_cell:
kernel_supports_daemonization = True
nb.cells.append(cleanup_cell)
client.execute_cell(
cell=cleanup_cell, cell_index=len(client.nb.cells) - 1, store_history=False
)
try:
client.execute_cell(
cell=cleanup_cell, cell_index=len(client.nb.cells) - 1, store_history=False
)
except KeyError as e:
# Same XEUS-based protocol violation as in cell_execute.
# Cleanup failures are non-fatal: trace and continue so the
# render still completes (kernel deps just won't be collected).
if e.args == ("status",):
trace("cleanup cell failed with missing 'status' in execute_reply; kernel deps unavailable")
else:
raise
nb.cells.pop()

# record kernel deps after execution (picks up imports that occurred
Expand Down Expand Up @@ -563,12 +572,26 @@ def cell_execute(client, cell, index, execution_count, eval_default, store_histo
# execute (w/o yaml options so that cell magics work)
source = cell.source
cell.source = nb_strip_yaml_options(client, cell.source)
cell = client.execute_cell(
cell=cell,
cell_index=index,
execution_count=execution_count,
store_history=store_history,
)
try:
cell = client.execute_cell(
cell=cell,
cell_index=index,
execution_count=execution_count,
store_history=store_history,
)
except KeyError as e:
# Some kernels (e.g. XEUS-based Maple) omit 'status' from
# execute_reply on error, violating the Jupyter protocol.
# Record the error in the cell outputs rather than crashing.
if e.args == ("status",):
cell.outputs.append(nbformat.v4.new_output(
output_type="error",
ename="KernelProtocolError",
evalue="Kernel returned execute_reply without status field",
traceback=[],
))
else:
raise
cell.source = source

# if lines_to_next_cell is 0 then fix it to be 1
Expand Down
Loading