Skip to content

One script with kind "Expression" throws in WorkArea.attaching and blanks the entire UI #433

Description

@noocyte

One script with kind: "Expression" throws in WorkArea.attaching and blanks the entire UI

Environment

NetPad 0.12.0, netpad-0.12.0-linux-amd64.deb (Electron variant)
OS Ubuntu 26.04 LTS
SDKs .NET 9.0.119 and .NET 10.0.110

Symptom

The app starts, the window renders, and a script tab loads with working syntax highlighting,
CodeLens and inlay hints — but there is no Explorer pane, no Output pane and no Namespaces
pane
, and View → Explorer (Alt+E), View → Output (Ctrl+R) and View → Namespaces
(Alt+N) all do nothing when clicked.

Nothing is surfaced to the user: no toast, no error dialog, and the backend log
(~/.local/share/NetPad/Logs/) is completely clean. From the outside it looks like the pane
toggles are simply broken, which sent me chasing GPU/Wayland and stale-state theories for a
while before I opened DevTools.

Root cause

The renderer console shows:

Uncaught (in promise) Error: Unhandled script kind: Expression
    at ViewableAppScriptDocument.getLanguageFromScriptKind (…bundle.js:1:233246)
    at new ViewableAppScriptDocument (…bundle.js:1:232788)
    at WorkArea.createViewableAppScriptDocument (…bundle.js:1:183353)
    at …bundle.js:1:180583
    at Array.map (<anonymous>)
    at WorkArea.attaching (…bundle.js:1:180571)
    at Controller.$t
    at Controller.bind
    at Controller.activate

WorkArea.attaching does an Array.map over the open scripts to build viewable documents.
getLanguageFromScriptKind has no case for Expression, so it throws — and because the throw
escapes the map, WorkArea.attaching aborts and the whole work area never mounts. The pane
toggles then have nothing to toggle.

So a single script with an unhandled kind takes down the entire UI, and one of mine did.
92 scripts, 91 Program, 1 Expression.

Reproduction

The offending script was empty apart from its config line:

c0ab4f47-4ec6-5e9a-8b33-bbef8f65412d
{"config":{"kind":"Expression","targetFrameworkVersion":"DotNet10","optimizationLevel":"Debug","useAspNet":false,"namespaces":["System", …],"references":[]},"dataConnection":null}
#Code

  1. Place a .netpad file with "kind":"Expression" in the scripts directory.
  2. Open it so it lands in session.openScripts (~/.local/share/NetPad/key-values.txt).
  3. Restart NetPad — the work area no longer mounts, and it stays broken across restarts
    because the script is reopened from the persisted session.

Changing that one file to "kind":"Program" restores the UI completely.

Where the Expression kind came from

The LINQPad import. The original query was:

<Query Kind="Expression" />

LINQPad's Expression kind is imported and persisted by the backend, but the frontend has no
mapping for it — so the two sides disagree about what kinds are valid. Anyone importing a
LINQPad library containing an expression-kind query will hit this, and the failure gives no
indication of which script or which setting is responsible.

Suggested fix

Two independent things, both worth doing:

  1. Handle Expression in getLanguageFromScriptKind (map it to C#), or reject the kind at
    import time and convert it to Program/Statements so it can never be persisted.
  2. Make WorkArea.attaching resilient. Wrap the per-script
    createViewableAppScriptDocument call so one bad document is skipped — logged and surfaced
    as a notification naming the offending script — instead of aborting the entire work area.
    Even once Expression is handled, any future unmapped kind or malformed script would
    otherwise reproduce a total UI blackout with no user-visible error.

The second point is the important one: the failure mode is drastically out of proportion to the
cause, and gives the user nothing to go on.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions