Skip to content

WhatsApp: honor outbound mediaMaxMb#38097

Merged
vincentkoc merged 7 commits intomainfrom
vincentkoc-code/telegram-media-max-config
Mar 6, 2026
Merged

WhatsApp: honor outbound mediaMaxMb#38097
vincentkoc merged 7 commits intomainfrom
vincentkoc-code/telegram-media-max-config

Conversation

@vincentkoc
Copy link
Copy Markdown
Member

Summary

  • Problem: WhatsApp inbound media limits used channels.whatsapp.mediaMaxMb, but outbound sends skipped that cap and auto-replies still used agents.defaults.mediaMaxMb.
  • Why it matters: operators could configure one WhatsApp media limit and still get different outbound behavior, especially across direct sends vs auto-replies.
  • What changed: outbound sends and auto-replies now resolve media caps from channels.whatsapp.mediaMaxMb, including per-account overrides; docs/tests/changelog were updated to match.
  • What did NOT change (scope boundary): LINE and Nextcloud Talk remain unchanged because their outbound paths still send media URLs/references rather than uploading channel-owned binary media.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

User-visible / Behavior Changes

  • WhatsApp outbound media sends now honor channels.whatsapp.mediaMaxMb instead of bypassing channel-level media caps.
  • WhatsApp outbound auto-replies now use the same channel-level cap, including channels.whatsapp.accounts.<accountId>.mediaMaxMb overrides.

Security Impact (required)

  • New permissions/capabilities? (Yes/No) No
  • Secrets/tokens handling changed? (Yes/No) No
  • New/changed network calls? (Yes/No) No
  • Command/tool execution surface changed? (Yes/No) No
  • Data access scope changed? (Yes/No) No
  • If any Yes, explain risk + mitigation:

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Node 22 / pnpm
  • Model/provider: N/A
  • Integration/channel (if any): WhatsApp
  • Relevant config (redacted): channels.whatsapp.mediaMaxMb, channels.whatsapp.accounts.<accountId>.mediaMaxMb

Steps

  1. Configure WhatsApp with a custom channels.whatsapp.mediaMaxMb (and optionally an account override).
  2. Send outbound media directly and trigger an outbound auto-reply with media.
  3. Verify the media loader receives the configured byte cap in both paths.

Expected

  • Outbound WhatsApp media honors the same channel-level cap as inbound media handling.

Actual

  • Direct outbound sends ignored the WhatsApp cap and auto-replies used agents.defaults.mediaMaxMb instead.

Evidence

Attach at least one:

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios: direct outbound WhatsApp media sends respect account-aware caps; auto-reply media compression/send path respects root and per-account WhatsApp caps.
  • Edge cases checked: account override precedence for outbound sends and auto-replies.
  • What you did not verify: live WhatsApp delivery against a real linked account.

Compatibility / Migration

  • Backward compatible? (Yes/No) Yes
  • Config/env changes? (Yes/No) No
  • Migration needed? (Yes/No) No
  • If yes, exact upgrade steps:

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly: revert this PR or pin channels.whatsapp.mediaMaxMb to a known-safe value.
  • Files/config to restore: src/web/outbound.ts, src/web/auto-reply/monitor.ts
  • Known bad symptoms reviewers should watch for: outbound WhatsApp media unexpectedly rejected or oversized media no longer compressed under the configured cap.

Risks and Mitigations

  • Risk: existing operators who relied on agents.defaults.mediaMaxMb for WhatsApp auto-replies may see the WhatsApp channel cap take precedence instead.
    • Mitigation: docs now point to channels.whatsapp.mediaMaxMb, and the effective default remains 50MB to match existing WhatsApp channel docs.

@vincentkoc vincentkoc self-assigned this Mar 6, 2026
@openclaw-barnacle openclaw-barnacle bot added docs Improvements or additions to documentation channel: bluebubbles Channel integration: bluebubbles channel: discord Channel integration: discord channel: telegram Channel integration: telegram channel: whatsapp-web Channel integration: whatsapp-web gateway Gateway runtime size: M maintainer Maintainer-authored PR labels Mar 6, 2026
@vincentkoc vincentkoc force-pushed the vincentkoc-code/telegram-media-max-config branch from 37ef754 to cfe2a34 Compare March 6, 2026 16:08
@vincentkoc vincentkoc marked this pull request as ready for review March 6, 2026 16:08
@vincentkoc vincentkoc merged commit 222d635 into main Mar 6, 2026
10 checks passed
@vincentkoc vincentkoc deleted the vincentkoc-code/telegram-media-max-config branch March 6, 2026 16:08
@openclaw-barnacle openclaw-barnacle bot added size: S and removed channel: bluebubbles Channel integration: bluebubbles channel: discord Channel integration: discord channel: telegram Channel integration: telegram gateway Gateway runtime size: M labels Mar 6, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 6, 2026

Greptile Summary

This PR correctly fixes a behavioral inconsistency in WhatsApp media handling by routing both outbound direct sends and auto-reply sends through resolveWhatsAppMediaMaxBytes, which honors channels.whatsapp.mediaMaxMb (and per-account overrides) rather than the previously used agents.defaults.mediaMaxMb. The core implementation is sound.

Key changes:

  • New resolveWhatsAppMediaMaxBytes helper centralizes WhatsApp-specific media cap resolution with a sane 50 MB default
  • outbound.ts resolves the account at call time and correctly applies per-account overrides, verified by the unit test that asserts on the maxBytes passed to loadWebMedia
  • monitor.ts replaces the agents.defaults.mediaMaxMb fallback logic with a call to the new helper; each account's monitor instance correctly resolves its own account-specific cap at startup
  • The production architecture ensures correct per-account behavior since each monitored account runs its own monitor instance with the proper tuning.accountId

Test coverage concern:
The "prefers per-account WhatsApp media caps for outbound auto-replies" test does not actually exercise per-account cap behavior. The monitor is started without tuning.accountId, so it resolves the default account and uses the root-level 1 MB cap. When the message is dispatched with accountId: "work", this only affects routing — the media cap remains 1 MB (not the work account's 0.1 MB override). The assertion passes coincidentally because a 256×256 solid-color image compresses to a very small JPEG regardless of the cap. Consider starting the monitor with tuning.accountId = "work" to properly test this behavior.

Confidence Score: 4/5

  • Safe to merge; the production implementation and outbound logic are correct. One test has a coverage gap but no production bug.
  • The core implementation correctly routes both outbound sends and auto-replies through per-account media cap resolution. Outbound direct sends are properly tested with account-specific overrides. The auto-reply test for per-account caps contains a coverage gap (monitor started for default account, message dispatched for work account), but this does not reflect a production defect since each account's monitor instance is started with the correct accountId in production. The test passes coincidentally due to image compression properties rather than actually verifying per-account behavior.
  • src/web/auto-reply.web-auto-reply.compresses-common-formats-jpeg-cap.test.ts — the per-account cap test should be rewritten to start the monitor with the correct accountId to properly exercise the claimed behavior.

Last reviewed commit: cfe2a34

Comment on lines +246 to +291
it("prefers per-account WhatsApp media caps for outbound auto-replies", async () => {
const bigPng = await sharp({
create: {
width: 256,
height: 256,
channels: 3,
background: { r: 255, g: 0, b: 0 },
},
})
.png({ compressionLevel: 0 })
.toBuffer();
expect(bigPng.length).toBeGreaterThan(SMALL_MEDIA_CAP_BYTES);

setLoadConfigMock(() => ({
channels: {
whatsapp: {
allowFrom: ["*"],
mediaMaxMb: 1,
accounts: {
work: {
mediaMaxMb: SMALL_MEDIA_CAP_MB,
},
},
},
},
}));

try {
const sendMedia = vi.fn();
const { reply, dispatch } = await setupSingleInboundMessage({
resolverValue: { text: "hi", mediaUrl: "https://example.com/account-big.png" },
sendMedia,
});
const fetchMock = mockFetchMediaBuffer(bigPng, "image/png");

await dispatch("msg-account-cap", { accountId: "work" });

const payload = getSingleImagePayload(sendMedia);
expect(payload.image.length).toBeLessThanOrEqual(SMALL_MEDIA_CAP_BYTES);
expect(payload.mimetype).toBe("image/jpeg");
expect(reply).not.toHaveBeenCalled();
fetchMock.mockRestore();
} finally {
resetLoadConfigMock();
}
});
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.

This test may not actually verify per-account cap behavior. The monitor is started via setupSingleInboundMessage without a tuning.accountId, so monitorWebChannel resolves the default account using the root-level mediaMaxMb: 1. That means maxMediaBytes = 1 MB throughout the monitor's lifetime.

When dispatch("msg-account-cap", { accountId: "work" }) is called, msg.accountId = "work" is used only for routing — maxMediaBytes in processMessage and deliverWebReply remains 1 MB (the default account's cap), not the work account's 0.1 MB cap.

The assertion payload.image.length <= SMALL_MEDIA_CAP_BYTES most likely passes coincidentally: a 256×256 solid-red image produces a JPEG of only a few KB regardless of the cap, so the test would pass even if the per-account override was never applied.

To correctly test per-account cap behavior, the monitor should be started for the "work" account so it actually resolves and applies the 0.1 MB override:

// Start the monitor with tuning.accountId = "work" so account.mediaMaxMb = 0.1 is used
await monitorWebChannel(false, listenerFactory, false, resolver, undefined, undefined, {
  accountId: "work",
});
// Then dispatch a plain message (no accountId override needed — monitor IS the work account)
await dispatch("msg-account-cap");

Alternatively, use a non-trivially-compressible image (e.g. random-noise pixels) together with two cap levels that produce measurably different output sizes, so the assertion fails when the wrong cap is applied.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/web/auto-reply.web-auto-reply.compresses-common-formats-jpeg-cap.test.ts
Line: 246-291

Comment:
This test may not actually verify per-account cap behavior. The monitor is started via `setupSingleInboundMessage` without a `tuning.accountId`, so `monitorWebChannel` resolves the *default* account using the root-level `mediaMaxMb: 1`. That means `maxMediaBytes = 1 MB` throughout the monitor's lifetime.

When `dispatch("msg-account-cap", { accountId: "work" })` is called, `msg.accountId = "work"` is used only for routing — `maxMediaBytes` in `processMessage` and `deliverWebReply` remains `1 MB` (the default account's cap), not the work account's `0.1 MB` cap.

The assertion `payload.image.length <= SMALL_MEDIA_CAP_BYTES` most likely passes coincidentally: a 256×256 solid-red image produces a JPEG of only a few KB regardless of the cap, so the test would pass even if the per-account override was never applied.

To correctly test per-account cap behavior, the monitor should be started for the "work" account so it actually resolves and applies the `0.1 MB` override:

```ts
// Start the monitor with tuning.accountId = "work" so account.mediaMaxMb = 0.1 is used
await monitorWebChannel(false, listenerFactory, false, resolver, undefined, undefined, {
  accountId: "work",
});
// Then dispatch a plain message (no accountId override needed — monitor IS the work account)
await dispatch("msg-account-cap");
```

Alternatively, use a non-trivially-compressible image (e.g. random-noise pixels) together with two cap levels that produce measurably different output sizes, so the assertion fails when the wrong cap is applied.

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

mrosmarin added a commit to mrosmarin/openclaw that referenced this pull request Mar 6, 2026
* main:
  Mattermost: harden interaction callback binding (openclaw#38057)
  WhatsApp: honor outbound mediaMaxMb (openclaw#38097)
  openai-image-gen: validate --background and --style options (openclaw#36762)
  Docs: align BlueBubbles media cap wording
  Telegram/Discord: honor outbound mediaMaxMb uploads (openclaw#38065)
  CI: run changed-scope on main pushes
  Skills/nano-banana-pro: clarify MEDIA token comment (openclaw#38063)
  nano-banana-pro: respect explicit --resolution when editing images (openclaw#36880)
  CI: drop unused install-smoke bootstrap
  fix(nano-banana-pro): remove space after MEDIA: token in generate_image.py (openclaw#18706)
  docs: context engine
  docs(config): list the context engine plugin slot
  docs(plugins): add context-engine manifest kind example
  docs(plugins): document context engine slots and registration
  docs(protocol): document slash-delimited schema lookup plugin ids
  docs(tools): document slash-delimited config schema lookup paths
  fix(session): tighten direct-session webchat routing matching (openclaw#37867)
  feature(context): extend plugin system to support custom context management (openclaw#22201)
  Gateway: allow slash-delimited schema lookup paths
ant1eicher pushed a commit to ant1eicher/openclaw that referenced this pull request Mar 6, 2026
* WhatsApp: add media cap helper

* WhatsApp: cap outbound media loads

* WhatsApp: align auto-reply media caps

* WhatsApp: add outbound media cap test

* WhatsApp: update auto-reply cap tests

* Docs: update WhatsApp media caps

* Changelog: note WhatsApp media cap fix
Saitop pushed a commit to NomiciAI/openclaw that referenced this pull request Mar 8, 2026
* WhatsApp: add media cap helper

* WhatsApp: cap outbound media loads

* WhatsApp: align auto-reply media caps

* WhatsApp: add outbound media cap test

* WhatsApp: update auto-reply cap tests

* Docs: update WhatsApp media caps

* Changelog: note WhatsApp media cap fix
jenawant pushed a commit to jenawant/openclaw that referenced this pull request Mar 10, 2026
* WhatsApp: add media cap helper

* WhatsApp: cap outbound media loads

* WhatsApp: align auto-reply media caps

* WhatsApp: add outbound media cap test

* WhatsApp: update auto-reply cap tests

* Docs: update WhatsApp media caps

* Changelog: note WhatsApp media cap fix
dhoman pushed a commit to dhoman/chrono-claw that referenced this pull request Mar 11, 2026
* WhatsApp: add media cap helper

* WhatsApp: cap outbound media loads

* WhatsApp: align auto-reply media caps

* WhatsApp: add outbound media cap test

* WhatsApp: update auto-reply cap tests

* Docs: update WhatsApp media caps

* Changelog: note WhatsApp media cap fix
senw-developers pushed a commit to senw-developers/va-openclaw that referenced this pull request Mar 17, 2026
* WhatsApp: add media cap helper

* WhatsApp: cap outbound media loads

* WhatsApp: align auto-reply media caps

* WhatsApp: add outbound media cap test

* WhatsApp: update auto-reply cap tests

* Docs: update WhatsApp media caps

* Changelog: note WhatsApp media cap fix
V-Gutierrez pushed a commit to V-Gutierrez/openclaw-vendor that referenced this pull request Mar 17, 2026
* WhatsApp: add media cap helper

* WhatsApp: cap outbound media loads

* WhatsApp: align auto-reply media caps

* WhatsApp: add outbound media cap test

* WhatsApp: update auto-reply cap tests

* Docs: update WhatsApp media caps

* Changelog: note WhatsApp media cap fix
alexey-pelykh pushed a commit to remoteclaw/remoteclaw that referenced this pull request Mar 20, 2026
* WhatsApp: add media cap helper

* WhatsApp: cap outbound media loads

* WhatsApp: align auto-reply media caps

* WhatsApp: add outbound media cap test

* WhatsApp: update auto-reply cap tests

* Docs: update WhatsApp media caps

* Changelog: note WhatsApp media cap fix

(cherry picked from commit 222d635)
alexey-pelykh pushed a commit to remoteclaw/remoteclaw that referenced this pull request Mar 20, 2026
* WhatsApp: add media cap helper

* WhatsApp: cap outbound media loads

* WhatsApp: align auto-reply media caps

* WhatsApp: add outbound media cap test

* WhatsApp: update auto-reply cap tests

* Docs: update WhatsApp media caps

* Changelog: note WhatsApp media cap fix

(cherry picked from commit 222d635)
alexey-pelykh added a commit to remoteclaw/remoteclaw that referenced this pull request Mar 20, 2026
* fix(subagents): recover announce cleanup after kill/complete race

(cherry picked from commit 2f86ae7)

* feat(hooks): emit compaction lifecycle hooks (openclaw#16788)

(cherry picked from commit 71ec421)

* fix(agent): harden undici stream timeouts for long openai-completions runs

(cherry picked from commit 05fb16d)

* fix(agents): allow configured ollama endpoints without dummy api keys

(cherry picked from commit 36afd1b)

* feat(openai): add gpt-5.4 support for API and Codex OAuth (openclaw#36590)

Co-authored-by: Tyler Yust <[email protected]>
(cherry picked from commit 5d4b040)

* Fix failover for zhipuai 1310 Weekly/Monthly Limit Exhausted (openclaw#33813)

Co-authored-by: zhouhe-xydt <[email protected]>
Co-authored-by: altaywtf <[email protected]>
(cherry picked from commit a65d70f)

* fix(failover): classify HTTP 402 as rate_limit when payload indicates usage limit (openclaw#30484) (openclaw#36802)

Co-authored-by: Val Alexander <[email protected]>
(cherry picked from commit 01b2017)

* feat(onboarding): add web search to onboarding flow (openclaw#34009)

* add web search to onboarding flow

* remove post onboarding step (now redundant)

* post-onboarding nudge if no web search set up

* address comments

* fix test mocking

* add enabled: false assertion to the no-key test

* --skip-search cli flag

* use provider that a user has a key for

* add assertions, replace the duplicated switch blocks

* test for quickstart fast-path with existing config key

* address comments

* cover quickstart falls through to key test

* bring back key source

* normalize secret inputs instead of direct string trimming

* preserve enabled: false if it's already set

* handle missing API keys in flow

* doc updates

* hasExistingKey to detect both plaintext strings and SecretRef objects

* preserve enabled state only on the "keep current" paths

* add test for preserving

* better gate flows

* guard against invalid provider values in config

* Update src/commands/configure.wizard.ts

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* format fix

* only mentions env var when it's actually available

* search apiKey fields now typed as SecretInput

* if no provider check if any search provider key is detectable

* handle both kimi keys

* remove .filter(Boolean)

* do not disable web_search after user enables it

* update resolveSearchProvider

* fix(onboarding): skip search key prompt in ref mode

* fix: add onboarding web search step (openclaw#34009) (thanks @kesku)

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Shadow <[email protected]>
(cherry picked from commit 3d7bc59)

* fix(ci): restore protocol and schema checks (openclaw#37470)

(cherry picked from commit ee6f7b1)

* Infra: require explicit opt-in for prerelease npm installs (openclaw#38117)

* Infra: tighten npm registry spec parsing

* Infra: block implicit prerelease npm installs

* Plugins: cover prerelease install policy

* Infra: add npm registry spec tests

* Hooks: cover prerelease install policy

* Docs: clarify plugin guide version policy

* Docs: clarify plugin install version policy

* Docs: clarify hooks install version policy

* Docs: clarify hook pack version policy

(cherry picked from commit f392b81)

* ci: trigger workflow

* fix: resolve cherry-pick adaptation failures from upstream web search commit

- Add missing hasConfiguredSecretInput() to types.secrets.ts
- Add SecretInput import to types.tools.ts for apiKey fields
- Replace OpenClawConfig with RemoteClawConfig in onboard-search
- Remove non-existent DEFAULT_SECRET_PROVIDER_ALIAS import
- Remove invalid 'provider' field from SecretRef literal
- Stub resolveSyntheticLocalProviderAuth (models.providers was gutted)
- Replace undefined registerRun/emitLifecycleEnd test helpers with
  existing mod.registerSubagentRun/lifecycleHandler patterns

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* Plugins: clarify registerHttpHandler migration errors (openclaw#36794)

* Changelog: note plugin HTTP route migration diagnostics

* Tests: cover registerHttpHandler migration diagnostics

* Plugins: clarify registerHttpHandler migration errors

* Tests: cover registerHttpHandler diagnostic edge cases

* Plugins: tighten registerHttpHandler migration hint

(cherry picked from commit d4021f4)

* Plugins: avoid false integrity drift prompts on unpinned updates (openclaw#37179)

* Plugins: skip drift prompts for unpinned updates

* Plugins: cover unpinned integrity update behavior

(cherry picked from commit 428d176)

* docs(protocol): document slash-delimited schema lookup plugin ids

(cherry picked from commit f788ba1)

* docs(plugins): document context engine slots and registration

(cherry picked from commit eb2eeba)

* docs(plugins): add context-engine manifest kind example

(cherry picked from commit 7cc3376)

* docs(config): list the context engine plugin slot

(cherry picked from commit 5470337)

* fix: Windows: openclaw plugins install fails with spawn EINVAL

Fixes openclaw#7631

(cherry picked from commit d000316)

* fix(whatsapp): remove implicit [openclaw] self-chat prefix

(cherry picked from commit 4d9134f)

* WhatsApp: honor outbound mediaMaxMb (openclaw#38097)

* WhatsApp: add media cap helper

* WhatsApp: cap outbound media loads

* WhatsApp: align auto-reply media caps

* WhatsApp: add outbound media cap test

* WhatsApp: update auto-reply cap tests

* Docs: update WhatsApp media caps

* Changelog: note WhatsApp media cap fix

(cherry picked from commit 222d635)

* fix(mattermost): allow reachable interaction callback URLs (openclaw#37543)

Merged via squash.

Prepared head SHA: 4d59373
Co-authored-by: mukhtharcm <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Reviewed-by: @mukhtharcm

(cherry picked from commit 4a80d48)

* Mattermost: harden interaction callback binding (openclaw#38057)

(cherry picked from commit a274ef9)

* chore: code/dead tests cleanup (openclaw#38286)

* Discord: assert bot-self filter queue guard

* Tests: remove dead gateway SIGTERM placeholder

(cherry picked from commit 38f46e8)

* Delete changelog/fragments directory

(cherry picked from commit 8f69e07)

* fix(feishu): restore explicit media request timeouts

(cherry picked from commit b127333)

* fix: adapt upstream naming to fork conventions

Replace OpenClawConfig with RemoteClawConfig, openclaw/plugin-sdk with
remoteclaw/plugin-sdk, and fix import paths for fork type exports.

* fix: resolve type errors from upstream cherry-picks

- Add missing RemoteClawConfig import in discord test
- Use spread with as-any for feishu SDK timeout property
- Remove allowUnresolvedSecretRef from mattermost test

* ci: re-trigger CI after force push

* fix: revert unintended onboarding changes from linter bleed

* ci: sync PR head with branch

---------

Co-authored-by: Vignesh Natarajan <[email protected]>
Co-authored-by: Vincent Koc <[email protected]>
Co-authored-by: dorukardahan <[email protected]>
Co-authored-by: Tyler Yust <[email protected]>
Co-authored-by: zhouhe-xydt <[email protected]>
Co-authored-by: zhouhe-xydt <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Co-authored-by: Xinhua Gu <[email protected]>
Co-authored-by: Val Alexander <[email protected]>
Co-authored-by: Kesku <[email protected]>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Shadow <[email protected]>
Co-authored-by: Altay <[email protected]>
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
Co-authored-by: 0xlin2023 <[email protected]>
Co-authored-by: Muhammed Mukhthar CM <[email protected]>
Co-authored-by: Ayaan Zaidi <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: whatsapp-web Channel integration: whatsapp-web docs Improvements or additions to documentation maintainer Maintainer-authored PR size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant