Skip to content

Keep the plot origin when a render is held past source() - #1391

Merged
midleman merged 3 commits into
mainfrom
mi/plot-origin-survives-held-render
Sep 8, 2026
Merged

Keep the plot origin when a render is held past source()#1391
midleman merged 3 commits into
mainfrom
mi/plot-origin-survives-held-render

Conversation

@midleman

@midleman midleman commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Fixes #1334.

Summary

A plot created inside source() could lose its origin, leaving the Plots pane with no source file and no way to recover it.

  • hook_mode() only captured the origin on the has_changes false->true edge, so a new page starting while earlier changes were pending never re-captured after new_positron_page() cleared the snapshot
  • graphics_on_did_execute_request() cleared the snapshot at the end of every request, so a render held into a later request lost it
  • Now captures whenever no snapshot is pending, and drops the end-of-request clear as redundant with the new-page clear
  • Adds test_plot_origin_survives_hold_across_source, which fails on main inside the assertion and passes with the fix

E2E Triage Diagnosis

🟢 High confidence -- Plot origin is lost on the source() path when the origin snapshot is dropped before process_changes consumes it, leaving the fallback to run after source() popped the context stack
  • Test: Plot File Attribution > R - Plot origin shows source file after run file command
  • Targeted failure: Error: expect(locator).toBeVisible() failed
  • Signal: Observed via file probes in a RED ark integration test: push_source_context -> EAGER CAPTURE succeeds -> new_positron_page clear wipes it -> hook_mode skips re-capture (old_has_changes=true) -> end-of-request clear in graphics_on_did_execute_request drops it again -> pop_source_context -> take_pending_origin FALLBACK -> None. The end-of-request clear is the decisive path for a render held across requests. Plot renders and the metadata RPC succeeds, but .plot-origin-file never enters the DOM. Local e2e did NOT reproduce (10/10 green on macOS, origin consumed inside the same request), so the CI route is predicted, not observed.
  • Frequency: 32/137 runs (23.4%) on main, ubuntu/electron
  • Hypothesis: race

A plot created inside `source()` gets its origin from the source context
stack, which `source()`'s `defer()` pops on the way out. The origin is
snapshotted eagerly at drawing time to survive that, but two things could
drop the snapshot before `process_changes()` consumed it:

- `hook_mode()` only captured on the `has_changes` false->true edge, so a
  new page starting while earlier changes were still pending (e.g. under
  `dev.hold()`) never re-captured after `new_positron_page()` cleared it.
- `graphics_on_did_execute_request()` cleared the snapshot at the end of
  every request, so a render held into a later request lost it.

Capture whenever no snapshot is pending, and drop the end-of-request
clear, which is redundant now that the new-page clear is the only one
that has to hold. Without an origin the Plots pane silently shows no
source file, with no way to recover it.

Fixes #1334
The field and setter docs still described capturing on the has_changes
false->true edge, which the previous commit replaced.
@midleman
midleman marked this pull request as ready for review August 7, 2026 16:12
@midleman
midleman requested a review from lionel- August 7, 2026 16:12

@lionel- lionel- 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.

I've pushed an update to make sure a stale plot origin isn't mistakenly applied to a new plot, with a test.

However AFAIU I don't think this will fix #1334. All the plot hooks and callbacks are called deterministically on a single thread, and the dev.hold() in plot() (the E2E test calls plot()) is flushed on exit: https://github.com/r-devel/r-svn/blob/0017c9e54f90bdc4a10dd1f41a7afdf7cac8ac0e/src/library/graphics/R/plot.R#L79.

Still a good fix to have, even though it only fixes an unlikely case.

@midleman
midleman merged commit bb6f700 into main Sep 8, 2026
17 checks passed
@midleman
midleman deleted the mi/plot-origin-survives-held-render branch September 8, 2026 10:50
@github-actions github-actions Bot locked and limited conversation to collaborators Sep 8, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Plot origin lost on the source() / run-file path (no code_location fallback)

2 participants