Skip to content

fix: msgspec encoding for starlette user#9406

Merged
dmadisetti merged 4 commits into
mainfrom
dm/msgspec-type
Apr 27, 2026
Merged

fix: msgspec encoding for starlette user#9406
dmadisetti merged 4 commits into
mainfrom
dm/msgspec-type

Conversation

@dmadisetti

Copy link
Copy Markdown
Member

📝 Summary

This PR fixes a bug introduced in 0.23.3 where msgspec encoding fails on a starlette object, breaking sandbox home mode. This PR also adds typing to help mitigate these issues in the future.

Copilot AI review requested due to automatic review settings April 27, 2026 21:58
@vercel

vercel Bot commented Apr 27, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
marimo-docs Ready Ready Preview, Comment Apr 27, 2026 10:26pm

Request Review

@dmadisetti
dmadisetti requested review from manzt and mscolnick April 27, 2026 21:58
@dmadisetti dmadisetti added the bug Something isn't working label Apr 27, 2026
mscolnick
mscolnick previously approved these changes Apr 27, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes IPC msgspec serialization failures when Starlette authentication middleware attaches a BaseUser (e.g., SimpleUser) to the request scope, which previously broke sandbox home mode.

Changes:

  • Normalize request.scope["user"] and request.scope["meta"] into IPC-encodable dicts when building HTTPRequest.
  • Introduce an Encodable type alias to tighten and document which values are expected to round-trip across msgspec IPC boundaries.
  • Add regression tests covering Starlette user normalization and msgspec msgpack encoding.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/_runtime/test_requests.py Adds regression tests for Starlette user normalization and IPC msgpack encoding safety.
marimo/_types/encodable.py Introduces an Encodable type alias for msgspec IPC-safe payload types.
marimo/_runtime/commands.py Normalizes user/meta in HTTPRequest.from_request and tightens typing for IPC-serialized structures.
marimo/_messaging/context.py Adjusts typing around HTTPRequest.url access after tightening URL field types.
marimo/_code_mode/_context.py Updates typing/casts for request.meta access after tightening meta field types.

Comment on lines 23 to 28
# Convert headers to list of tuples as expected by Starlette
raw_headers = [(k.lower(), v) for k, v in (headers or {}).items()]
scope = {
scope: dict[str, Any] = {
"type": "http",
"method": "GET",
"headers": dict(raw_headers),

Copilot AI Apr 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment says headers are converted to a list of tuples "as expected by Starlette", but the scope ultimately stores a dict and the overridden headers property builds Headers(headers=...) from that dict. Please either update the comment to match the mock’s behavior, or store raw headers in the scope (e.g., bytes tuples) to more closely mirror Starlette’s ASGI scope shape.

Copilot uses AI. Check for mistakes.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 5 files

Architecture diagram
sequenceDiagram
    participant Client as "Web Client"
    participant Server as "Marimo Server (Starlette)"
    participant Auth as "Auth Middleware"
    participant CMD as "HTTPRequest (commands.py)"
    participant IPC as "msgspec Encoder"
    participant Kernel as "Marimo Kernel"

    Note over Client,Kernel: Request Execution Flow (e.g., Sandbox Home)

    Client->>Server: HTTP Request (GET /api/kernel/execute)
    
    Server->>Auth: Process Request Scope
    Auth-->>Server: Injects Starlette SimpleUser into scope
    
    Server->>CMD: HTTPRequest.from_request(request)
    
    rect rgb(240,240,240)
        Note over CMD: NEW: Normalization Boundary
        CMD->>CMD: NEW: _user_to_dict(user)
        Note right of CMD: Converts Starlette object<br/>to Encodable dict
        CMD->>CMD: NEW: _meta_to_dict(meta)
    end
    
    CMD-->>Server: Return serializable HTTPRequest
    
    Server->>IPC: CHANGED: msgspec.encode(request)
    
    alt Encoding Success
        IPC-->>Server: Binary Payload
        Server->>Kernel: Send Request Data via IPC
        Kernel->>Kernel: Execute User Code (mo.app_meta())
    else Encoding Failure (Fixed)
        Note over IPC: Previously failed on<br/>Starlette User objects
        IPC-->>Server: Raise TypeError
    end

    Note over Kernel: Code Execution Context
    Kernel->>Kernel: CHANGED: cast types for server_url/auth_token
    Kernel-->>Client: Result / Screenshot Data
Loading

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 3 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="marimo/_runtime/commands.py">

<violation number="1" location="marimo/_runtime/commands.py:132">
P2: Widening `user` from `dict[str, Encodable]` to `Encodable` weakens the type contract while `_user_to_dict` (the sole producer) always returns a dict. If a starlette user object is reaching this field un-converted, the fix should ensure `_user_to_dict` is called on that code path rather than loosening the type — an un-converted starlette object still won't be msgspec-encodable even under the `Encodable` (`Any`) annotation.

(Based on your team's feedback about requiring strict typing over Any.) [FEEDBACK_USED]</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.

Comment thread marimo/_runtime/commands.py
@dmadisetti
dmadisetti merged commit 67d2781 into main Apr 27, 2026
44 checks passed
@dmadisetti
dmadisetti deleted the dm/msgspec-type branch April 27, 2026 23:02
@github-actions

Copy link
Copy Markdown
Contributor

🚀 Development release published. You may be able to view the changes at https://marimo.app?v=0.23.4-dev15

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants