Skip to content

[APP-4267] Show Mermaid render failure callout#10432

Merged
zachlloyd merged 2 commits intomasterfrom
zach/app-4267-mermaid-failure-callout-specs
May 9, 2026
Merged

[APP-4267] Show Mermaid render failure callout#10432
zachlloyd merged 2 commits intomasterfrom
zach/app-4267-mermaid-failure-callout-specs

Conversation

@zachlloyd
Copy link
Copy Markdown
Contributor

@zachlloyd zachlloyd commented May 8, 2026

Description

Adds an explicit failure state for Mermaid diagrams so rendered markdown surfaces no longer leave users on an indefinite “Rendering Mermaid diagram…” placeholder when rendering fails or stays unresolved too long.

This PR:

  • Adds compact failed-layout sizing for Mermaid render failures while preserving the existing pending height for loading diagrams.
  • Extends the shared Image element with opt-in failed-load and load-timeout backup elements, preserving existing behavior for callers that do not opt in.
  • Wires Mermaid rendering to show Failed to render Mermaid diagram for permanent load failures and after the Mermaid render timeout.
  • Keeps Mermaid source, selection, copying, and markdown serialization semantics unchanged.
  • Adds PRODUCT and TECH specs for APP-4267.

Agent conversation: https://staging.warp.dev/conversation/2a1dc8f7-5ddb-4b22-bdea-384e2281624a

Linked Issue

https://linear.app/warpdotdev/issue/APP-4267/show-failure-callout-when-mermaid-diagram-rendering-gets-stuck

  • The linked issue is labeled ready-to-spec or ready-to-implement.
  • Where appropriate, screenshots or a short video of the implementation are included below (especially for user-visible or UI changes).

Testing

Automated validation:

  • cargo fmt --manifest-path /Users/zach/Projects/warp_3/Cargo.toml --all --check
  • PATH=/tmp/warp-corepack-bin:$PATH cargo nextest run --manifest-path /Users/zach/Projects/warp_3/Cargo.toml --no-fail-fast --workspace mermaid image
    • 121 tests passed, including the focused Mermaid/image tests and matching integration tests selected by those filters.
  • PATH=/tmp/warp-corepack-bin:$PATH cargo clippy --manifest-path /Users/zach/Projects/warp_3/Cargo.toml --workspace --all-targets --all-features --tests -- -D warnings

New/updated test coverage includes:

  • Mermaid layout uses the existing default height while loading.

  • Failed Mermaid assets use a compact failed-callout height.

  • Image prefers a provided failed-load element for failed assets.

  • Image falls back to the before-load element for failed assets when no failed-load element is provided.

  • Loading images switch to a timeout element after the configured timeout.

  • Timeout start state survives rebuilding an Image element for the same asset source.

  • I have manually tested my changes locally with ./script/run

Screenshots / Videos

Mermaid render failure callout captured from the PR branch with a forced Mermaid asset-load failure:

Mermaid render failure callout

Agent Mode

  • Warp Agent Mode - This PR was created via Warp's AI Agent Mode

CHANGELOG-BUG-FIX: Fixed Mermaid diagrams showing an indefinite rendering placeholder when rendering fails or times out.

Co-Authored-By: Oz oz-agent@warp.dev

zachlloyd and others added 2 commits May 7, 2026 18:08
Co-Authored-By: Oz <oz-agent@warp.dev>
Rebuild Mermaid block layout after visible layout-affecting asset loads complete in editable editor states, so permanent Mermaid render failures use the compact failure height instead of retaining the loading placeholder height.

Co-Authored-By: Oz <oz-agent@warp.dev>
@cla-bot cla-bot Bot added the cla-signed label May 8, 2026
@zachlloyd zachlloyd requested a review from zachbai May 9, 2026 19:33
@zachlloyd zachlloyd marked this pull request as ready for review May 9, 2026 19:33
@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 9, 2026

@zachlloyd

I'm starting a first review of this pull request.

You can view the conversation on Warp.

I completed the review and no human review was requested for this pull request.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

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

Overview

This PR adds an explicit Mermaid failure/timeout callout by extending the shared Image element with opt-in failed-load and timeout backup elements, then wiring Mermaid diagrams to use those states.

Concerns

  • The new process-global image timeout map can grow without bound because entries are only cleared from paint after an asset is later observed as loaded, failed, or evicted. Stuck renders and image elements removed before resolution leave their keys behind.

Security

  • User-controlled Markdown can introduce many unique Mermaid asset sources, so the unbounded timeout map creates a resource-growth path in the renderer process.

Verdict

Found: 0 critical, 1 important, 0 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

};

lazy_static! {
static ref IMAGE_LOAD_TIMEOUT_STARTED_AT: Mutex<HashMap<u64, Instant>> =
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.

⚠️ [IMPORTANT] [SECURITY] This process-wide map is only cleared when paint later sees the asset as loaded, failed, or evicted; a stuck load or a removed image element leaves its timeout key forever, so user-controlled Mermaid sources can grow it without bound. Add expiry/eviction or tie this state to the asset cache lifecycle instead of an unbounded static map.

Comment on lines +163 to +168
pub fn on_load_failure(mut self, element: Box<dyn Element>) -> Self {
self.failed_to_load_element = Some(element);
self
}

pub fn on_load_timeout(mut self, timeout: Duration, element: Box<dyn Element>) -> Self {
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.

Its fine cuz this was the pattern already used for before_load_element but it probably wouldve been better to make these kind of API take a closure so the element doesn't need to be unnecessarily constructed if its not gonna be used

@zachlloyd zachlloyd closed this May 9, 2026
@zachlloyd zachlloyd reopened this May 9, 2026
@zachlloyd zachlloyd merged commit c8d3908 into master May 9, 2026
53 of 54 checks passed
@zachlloyd zachlloyd deleted the zach/app-4267-mermaid-failure-callout-specs branch May 9, 2026 22:36
@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 9, 2026

@zachlloyd

I'm starting a first review of this pull request.

You can view the conversation on Warp.

I completed the review and no human review was requested for this pull request.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

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

Overview

This PR adds explicit Mermaid image failure and timeout fallback rendering, compact layout for permanent Mermaid load failures, and focused coverage for the shared Image fallback behavior and Mermaid sizing.

Concerns

  • No blocking correctness, security, or error-handling concerns found in the reviewed diff.

Verdict

Found: 0 critical, 0 important, 0 suggestions

Approve

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants