Skip to content

fix(bun): use modulePath for jitiFilename in bundled plugin loader (#69783)#70080

Closed
EronFan wants to merge 9 commits into
openclaw:mainfrom
EronFan:fix/69783-bun-jiti
Closed

fix(bun): use modulePath for jitiFilename in bundled plugin loader (#69783)#70080
EronFan wants to merge 9 commits into
openclaw:mainfrom
EronFan:fix/69783-bun-jiti

Conversation

@EronFan

@EronFan EronFan commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

Fixes #69783 — In Bun global install, import.meta.url in bundled plugins points to a cached path instead of the actual module path, causing jiti loader to hang. Changed to use modulePath parameter instead.

EronFan added 9 commits April 21, 2026 21:00
Root cause: tool runners capture startedAt = Date.now() before calling
createTaskRecord. By the time the registry sets createdAt = Date.now(),
a few ms may have passed, making startedAt < createdAt architecturally.

Fix: in createTaskRecord, clamp createdAt to be at least startedAt when
startedAt is provided and already in the past. This ensures the invariant
createdAt >= startedAt is always true for new records, eliminating the
false positive from the inconsistent_timestamps audit check.

Tests: new regression tests in task-registry.audit.test.ts covering:
- startedAt captured before registration (pre-clamp legacy input)
- terminal task with pre-createdAt startedAt (genuine ordering bug still caught)
- non-consecutive duplicate suppression in system-events (bundled fix)

Fixes openclaw#69229
@EronFan
EronFan requested a review from a team as a code owner April 22, 2026 08:43
@openclaw-barnacle openclaw-barnacle Bot added channel: telegram Channel integration: telegram channel: whatsapp-web Channel integration: whatsapp-web agents Agent runtime and tooling size: L labels Apr 22, 2026
@greptile-apps

greptile-apps Bot commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR bundles several independent fixes: the stated Bun fix (switching jitiFilename from import.meta.url to modulePath in all five plugin loader files), plus task-registry timestamp clamping, system-event deduplication, WhatsApp self-message skipping, Telegram media-type detection, sandbox bind-mount path resolution, pi-embedded-subscribe text-flush for custom providers, and new browser aria-snapshot ref resolution via getByRole.

  • P1 — nth dropped in aria node mapping (extensions/browser/src/browser/pw-tools-core.snapshot.ts:65): formatted.map((n) => ({ ref: n.ref, role: n.role, name: n.name || undefined })) omits n.nth, so refLocator never receives the index needed to disambiguate duplicate role+name elements, silently returning the wrong element for those refs.

Confidence Score: 4/5

Safe to merge after fixing the missing nth field in the aria snapshot node mapping.

One P1 bug: the nth field is dropped when storing aria snapshot nodes, causing refLocator to return the wrong element for duplicate-role/name nodes. All other changes (core Bun fix, timestamp clamping, dedup, self-message guard, bind mounts) look correct. The misleading test name is P2 only.

extensions/browser/src/browser/pw-tools-core.snapshot.ts (missing nth in node mapping), src/tasks/task-registry.audit.test.ts (misleading test name)

Prompt To Fix All With AI
This is a comment left during a code review.
Path: extensions/browser/src/browser/pw-tools-core.snapshot.ts
Line: 65

Comment:
**`nth` dropped when storing aria snapshot nodes**

The `nth` field from each `AriaSnapshotNode` is not included in the mapping, so it is never stored in `state.ariaSnapshotNodes`. When `refLocator` resolves an `ax<number>` ref whose original node had `nth` set (used to disambiguate multiple elements sharing the same role+name), it falls through to the plain `getByRole(role, { name, exact: true })` call without calling `.nth(...)`, silently returning the wrong (first) element.

```suggestion
    nodes: formatted.map((n) => ({ ref: n.ref, role: n.role, name: n.name || undefined, nth: n.nth })),
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/tasks/task-registry.audit.test.ts
Line: 129-153

Comment:
**Misleading test name — says "does not flag" but asserts the opposite**

The test is named `"does not flag inconsistent_timestamps when startedAt is captured before task registration"`, yet the assertion expects the `inconsistent_timestamps` finding to be present. The comment clarifies the intent (testing legacy pre-clamp data), but the name contradicts the assertion and will confuse future readers. Consider renaming to something like `"flags inconsistent_timestamps for legacy data with startedAt earlier than createdAt (pre-clamp)"`.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "fix(bun): use modulePath for jitiFilenam..." | Re-trigger Greptile

page,
cdpUrl: opts.cdpUrl,
targetId: opts.targetId,
nodes: formatted.map((n) => ({ ref: n.ref, role: n.role, name: n.name || undefined })),

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.

P1 nth dropped when storing aria snapshot nodes

The nth field from each AriaSnapshotNode is not included in the mapping, so it is never stored in state.ariaSnapshotNodes. When refLocator resolves an ax<number> ref whose original node had nth set (used to disambiguate multiple elements sharing the same role+name), it falls through to the plain getByRole(role, { name, exact: true }) call without calling .nth(...), silently returning the wrong (first) element.

Suggested change
nodes: formatted.map((n) => ({ ref: n.ref, role: n.role, name: n.name || undefined })),
nodes: formatted.map((n) => ({ ref: n.ref, role: n.role, name: n.name || undefined, nth: n.nth })),
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/browser/src/browser/pw-tools-core.snapshot.ts
Line: 65

Comment:
**`nth` dropped when storing aria snapshot nodes**

The `nth` field from each `AriaSnapshotNode` is not included in the mapping, so it is never stored in `state.ariaSnapshotNodes`. When `refLocator` resolves an `ax<number>` ref whose original node had `nth` set (used to disambiguate multiple elements sharing the same role+name), it falls through to the plain `getByRole(role, { name, exact: true })` call without calling `.nth(...)`, silently returning the wrong (first) element.

```suggestion
    nodes: formatted.map((n) => ({ ref: n.ref, role: n.role, name: n.name || undefined, nth: n.nth })),
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +129 to +153
it("does not flag inconsistent_timestamps when startedAt is captured before task registration", () => {
// Regression: tool runners capture startedAt = Date.now() before calling
// createTaskRecord. By the time the registry records createdAt = Date.now(),
// a few ms may have passed, making startedAt < createdAt architecturally.
// createTaskRecord clamps createdAt >= startedAt, so this state never
// persists — but we test the audit still handles the invariant correctly
// for pre-clamped record inputs (e.g. restored legacy data).
const startedAt = Date.parse("2026-03-30T00:00:00.000Z"); // older than createdAt
const createdAt = startedAt + 10; // 10 ms later
const findings = listTaskAuditFindings({
now: createdAt + 60_000,
tasks: [
createTask({
taskId: "ts-clock-skew",
status: "running",
createdAt,
startedAt, // intentionally earlier than createdAt (pre-clamp legacy state)
}),
],
});

expect(findings.map((f) => [f.code, f.detail])).toEqual([
["inconsistent_timestamps", "startedAt is earlier than createdAt"],
]);
});

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.

P2 Misleading test name — says "does not flag" but asserts the opposite

The test is named "does not flag inconsistent_timestamps when startedAt is captured before task registration", yet the assertion expects the inconsistent_timestamps finding to be present. The comment clarifies the intent (testing legacy pre-clamp data), but the name contradicts the assertion and will confuse future readers. Consider renaming to something like "flags inconsistent_timestamps for legacy data with startedAt earlier than createdAt (pre-clamp)".

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/tasks/task-registry.audit.test.ts
Line: 129-153

Comment:
**Misleading test name — says "does not flag" but asserts the opposite**

The test is named `"does not flag inconsistent_timestamps when startedAt is captured before task registration"`, yet the assertion expects the `inconsistent_timestamps` finding to be present. The comment clarifies the intent (testing legacy pre-clamp data), but the name contradicts the assertion and will confuse future readers. Consider renaming to something like `"flags inconsistent_timestamps for legacy data with startedAt earlier than createdAt (pre-clamp)"`.

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6a6740a79f

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +937 to +939
const scope = state.roleRefsFrameSelector
? page.frameLocator(state.roleRefsFrameSelector)
: page;

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.

P1 Badge Ignore stale frame selector for ax refs

This new ax<number> branch scopes lookups through state.roleRefsFrameSelector, but storeAriaSnapshotNodes never clears that field. If a user takes a frame-scoped role snapshot first (which sets roleRefsFrameSelector) and then takes an aria snapshot, later refLocator("ax...") calls are forced into the old frame and fail to find elements that are in the top document. That makes valid aria refs intermittently unusable depending on prior tool calls.

Useful? React with 👍 / 👎.

page,
cdpUrl: opts.cdpUrl,
targetId: opts.targetId,
nodes: formatted.map((n) => ({ ref: n.ref, role: n.role, name: n.name || undefined })),

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.

P2 Badge Preserve disambiguation when caching ax snapshot refs

The cached aria node metadata now keeps only {ref, role, name}. For pages with repeated accessible names (for example multiple button elements named "Submit"), different ax refs collapse to the same getByRole query, so click/fill paths can hit Playwright strict-mode ambiguity instead of the exact node the snapshot ref pointed to. refLocator already supports node.nth, but this mapper never populates it, so the disambiguation path is unreachable for real aria snapshots.

Useful? React with 👍 / 👎.

@steipete

Copy link
Copy Markdown
Contributor

Closing this in favor of the focused Bun/Jiti fix in #70073.

This branch contains the same jitiFilename direction plus several unrelated behavior changes, which makes it harder to review and already has a separate browser snapshot finding. Please split any still-needed non-Jiti fixes into focused PRs.

@steipete steipete added the duplicate This issue or pull request already exists label Apr 22, 2026
@steipete steipete closed this Apr 22, 2026
@prtags

prtags Bot commented Apr 23, 2026

Copy link
Copy Markdown

Related work from PRtags group heroic-newt-2cq0

Title: Open PR candidate: bundled plugin jitiFilename should use modulePath for #69783

Number Title
#70073 fix(plugins): use module path for bundled jiti loads
#70080* fix(bun): use modulePath for jitiFilename in bundled plugin loader (#69783)

* This PR

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

Labels

agents Agent runtime and tooling channel: telegram Channel integration: telegram channel: whatsapp-web Channel integration: whatsapp-web duplicate This issue or pull request already exists size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Bun global install hangs in openclaw infer image providers while loading bundled image providers

2 participants