Skip to content

fix(discord): clarify startup readiness log#51425

Merged
scoootscooob merged 2 commits intoopenclaw:mainfrom
scoootscooob:codex/discord-startup-status
Mar 21, 2026
Merged

fix(discord): clarify startup readiness log#51425
scoootscooob merged 2 commits intoopenclaw:mainfrom
scoootscooob:codex/discord-startup-status

Conversation

@scoootscooob
Copy link
Copy Markdown
Contributor

Summary

Describe the problem and fix in 2-5 bullets:

  • Problem: Discord startup logging could say logged in to discord before the gateway was actually READY.
  • Why it matters: during startup network failures or delayed gateway readiness, that message is misleading and makes operators think the channel is healthy when it is still waiting to connect.
  • What changed: extracted startup status formatting into a tiny helper and now log either discord client initialized ...; awaiting gateway readiness or logged in to discord ... based on actual gateway readiness.
  • What did NOT change (scope boundary): this does not alter Discord reconnect logic, startup retry behavior, or lifecycle state transitions.

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

  • Discord startup no longer claims the bot is logged in before the gateway is ready.
  • When identity is known but the gateway is still connecting, logs now say discord client initialized ...; awaiting gateway readiness.

Security Impact (required)

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

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Node 22 / pnpm test wrapper
  • Model/provider: not applicable
  • Integration/channel (if any): Discord monitor startup logging
  • Relevant config (redacted): Discord default account with bot identity present

Steps

  1. Evaluate the startup status message with a known bot identity before gateway readiness.
  2. Evaluate the startup status message again after gateway readiness.
  3. Run focused Discord tests for the new helper and the existing lifecycle behavior.

Expected

  • Before READY: discord client initialized ...; awaiting gateway readiness
  • After READY: logged in to discord ...

Actual

  • Before this patch, startup always logged logged in to discord... even when the gateway was not yet ready.

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:
    • pnpm test -- extensions/discord/src/monitor/startup-status.test.ts
    • pnpm test -- extensions/discord/src/monitor/provider.lifecycle.test.ts
    • manual smoke via node --import tsx for both helper outputs
  • Edge cases checked:
    • missing identity stays punctuation-clean
    • existing Discord lifecycle tests remain green
  • What you did not verify:
    • full repo test suite
    • live Discord gateway traffic against a real bot account

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.

Compatibility / Migration

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

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly: revert commit f7da963fa8f2649c53178f0f08bb03cddfc1e977
  • Files/config to restore:
    • extensions/discord/src/monitor/provider.ts
    • extensions/discord/src/monitor/startup-status.ts
  • Known bad symptoms reviewers should watch for:
    • Discord startup still claiming logged-in status while the gateway is not ready
    • startup logs missing identity or showing awkward punctuation

Risks and Mitigations

List only real risks for this PR. Add/remove entries as needed. If none, write None.

  • Risk: callers could accidentally diverge from the helper and reintroduce inconsistent startup wording later.
    • Mitigation: the status formatting now lives in one tiny helper with direct tests.

@openclaw-barnacle openclaw-barnacle bot added channel: discord Channel integration: discord size: XS maintainer Maintainer-authored PR labels Mar 21, 2026
@scoootscooob scoootscooob self-assigned this Mar 21, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 21, 2026

Greptile Summary

This PR fixes a misleading Discord startup log that previously claimed the bot was "logged in" before the gateway was actually ready. It extracts a small formatDiscordStartupStatusMessage helper that returns different messages depending on whether lifecycleGateway.isConnected is true, and adds a focused test suite for it.

  • startup-status.ts – new helper with clean, correct branching logic for the ready/not-ready states and optional identity suffix.
  • provider.ts – call-site is minimal; lifecycleGateway?.isConnected === true mirrors the existing guard immediately below, and botIdentity || undefined correctly collapses the empty-string sentinel.
  • startup-status.test.ts – three of four input combinations are tested; the gatewayReady: true + no botIdentity case is the only uncovered branch (low risk, but worth adding for symmetry).

Confidence Score: 5/5

  • Safe to merge — change is purely cosmetic (log message wording) with no behavioral or state-transition side effects.
  • The diff is extremely narrow: one new 10-line helper, its test file, and a two-line call-site change. No reconnect logic, lifecycle state, or data paths are touched. The only observation is a minor missing test branch that does not affect correctness.
  • No files require special attention.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: extensions/discord/src/monitor/startup-status.test.ts
Line: 4-30

Comment:
**Missing test case: `gatewayReady: true` without `botIdentity`**

The test suite covers three of the four meaningful input combinations but is missing the case where the gateway is ready but `botIdentity` is absent. Exercising that path ensures the `identitySuffix` branch in the ready state is also verified, keeping coverage symmetric with the non-ready cases.

```suggestion
  it("reports logged-in status only after the gateway is ready", () => {
    expect(
      formatDiscordStartupStatusMessage({
        gatewayReady: true,
        botIdentity: "bot-1 (Molty)",
      }),
    ).toBe("logged in to discord as bot-1 (Molty)");
  });

  it("reports logged-in status without identity suffix when identity is absent", () => {
    expect(
      formatDiscordStartupStatusMessage({
        gatewayReady: true,
      }),
    ).toBe("logged in to discord");
  });
```

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

Last reviewed commit: "Discord: clarify sta..."

Comment on lines +4 to +30
describe("formatDiscordStartupStatusMessage", () => {
it("reports logged-in status only after the gateway is ready", () => {
expect(
formatDiscordStartupStatusMessage({
gatewayReady: true,
botIdentity: "bot-1 (Molty)",
}),
).toBe("logged in to discord as bot-1 (Molty)");
});

it("reports client initialization while gateway readiness is still pending", () => {
expect(
formatDiscordStartupStatusMessage({
gatewayReady: false,
botIdentity: "bot-1 (Molty)",
}),
).toBe("discord client initialized as bot-1 (Molty); awaiting gateway readiness");
});

it("handles missing identity without awkward punctuation", () => {
expect(
formatDiscordStartupStatusMessage({
gatewayReady: false,
}),
).toBe("discord client initialized; awaiting gateway readiness");
});
});
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 Missing test case: gatewayReady: true without botIdentity

The test suite covers three of the four meaningful input combinations but is missing the case where the gateway is ready but botIdentity is absent. Exercising that path ensures the identitySuffix branch in the ready state is also verified, keeping coverage symmetric with the non-ready cases.

Suggested change
describe("formatDiscordStartupStatusMessage", () => {
it("reports logged-in status only after the gateway is ready", () => {
expect(
formatDiscordStartupStatusMessage({
gatewayReady: true,
botIdentity: "bot-1 (Molty)",
}),
).toBe("logged in to discord as bot-1 (Molty)");
});
it("reports client initialization while gateway readiness is still pending", () => {
expect(
formatDiscordStartupStatusMessage({
gatewayReady: false,
botIdentity: "bot-1 (Molty)",
}),
).toBe("discord client initialized as bot-1 (Molty); awaiting gateway readiness");
});
it("handles missing identity without awkward punctuation", () => {
expect(
formatDiscordStartupStatusMessage({
gatewayReady: false,
}),
).toBe("discord client initialized; awaiting gateway readiness");
});
});
it("reports logged-in status only after the gateway is ready", () => {
expect(
formatDiscordStartupStatusMessage({
gatewayReady: true,
botIdentity: "bot-1 (Molty)",
}),
).toBe("logged in to discord as bot-1 (Molty)");
});
it("reports logged-in status without identity suffix when identity is absent", () => {
expect(
formatDiscordStartupStatusMessage({
gatewayReady: true,
}),
).toBe("logged in to discord");
});
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/discord/src/monitor/startup-status.test.ts
Line: 4-30

Comment:
**Missing test case: `gatewayReady: true` without `botIdentity`**

The test suite covers three of the four meaningful input combinations but is missing the case where the gateway is ready but `botIdentity` is absent. Exercising that path ensures the `identitySuffix` branch in the ready state is also verified, keeping coverage symmetric with the non-ready cases.

```suggestion
  it("reports logged-in status only after the gateway is ready", () => {
    expect(
      formatDiscordStartupStatusMessage({
        gatewayReady: true,
        botIdentity: "bot-1 (Molty)",
      }),
    ).toBe("logged in to discord as bot-1 (Molty)");
  });

  it("reports logged-in status without identity suffix when identity is absent", () => {
    expect(
      formatDiscordStartupStatusMessage({
        gatewayReady: true,
      }),
    ).toBe("logged in to discord");
  });
```

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

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

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: f7da963fa8

ℹ️ 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 +976 to +980
runtime.log?.(
formatDiscordStartupStatusMessage({
gatewayReady: lifecycleGateway?.isConnected === true,
botIdentity: botIdentity || undefined,
}),
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Emit a READY success log after deferred Discord startup

When lifecycleGateway.isConnected is still false here, this path now logs discord client initialized ...; awaiting gateway readiness and never logs the old logged in to discord ... message later if READY arrives a few seconds afterwards. I checked extensions/discord/src/monitor/provider.lifecycle.ts, and the later READY path only pushes statusSink updates; it does not emit any follow-up success log. On slow-but-healthy startups, operators therefore lose the only positive Discord-ready marker they are still told to look for in docs/install/fly.md:133-138, so log-based startup verification regresses on exactly the scenario this change is trying to clarify.

Useful? React with 👍 / 👎.

@scoootscooob scoootscooob merged commit 9fb7845 into openclaw:main Mar 21, 2026
9 checks passed
@scoootscooob
Copy link
Copy Markdown
Contributor Author

Merged via squash.

Thanks @scoootscooob!

@aisle-research-bot
Copy link
Copy Markdown

aisle-research-bot bot commented Mar 21, 2026

🔒 Aisle Security Analysis

We found 1 potential security issue(s) in this PR:

# Severity Title
1 🔵 Low Discord startup log message allows CRLF/terminal escape injection via unsanitized bot identity

1. 🔵 Discord startup log message allows CRLF/terminal escape injection via unsanitized bot identity

Property Value
Severity Low
CWE CWE-117
Location extensions/discord/src/monitor/startup-status.ts:5-9

Description

The Discord monitor formats a startup status log line by directly concatenating botIdentity (derived from Discord API fields like username / globalName) into a string that is written to runtime.log.

If botIdentity contains control characters (e.g., \n, \r, \t, or other C0/C1 controls) or ANSI escape sequences (e.g., \x1b[), an attacker who can influence the bot's profile name can:

  • Forge or split log lines (CRLF injection / log forging)
  • Inject terminal escape sequences when logs are viewed in a terminal (e.g., clearing screen, hyperlink injection depending on terminal)
  • Confuse log-based alerting/monitoring that expects one event per line

Vulnerable code:

const identitySuffix = params.botIdentity ? ` as ${params.botIdentity}` : "";
return `logged in to discord${identitySuffix}`;

Data flow (as implemented in provider.ts):

  • botUserName is fetched from Discord (client.fetchUser("@​me")) and assigned from botUser?.username / botUser?.globalName
  • botIdentity is built using that value
  • The formatted string is passed to runtime.log?.(...)

Recommendation

Sanitize/neutralize untrusted identity text before embedding it into log/terminal output.

For example, strip ANSI escapes and remove/escape control characters before concatenation:

function sanitizeForLog(input: string): string {// Remove ANSI escape sequences
  const noAnsi = input.replace(/\x1b\[[0-9;]*[A-Za-z]/g, "");// Escape common whitespace controls and drop remaining control chars
  return noAnsi
    .replace(/\r/g, "\\r")
    .replace(/\n/g, "\\n")
    .replace(/\t/g, "\\t")
    .replace(/[\x00-\x1F\x7F-\x9F]/g, "");
}

export function formatDiscordStartupStatusMessage(params: {
  gatewayReady: boolean;
  botIdentity?: string;
}): string {
  const safeIdentity = params.botIdentity ? sanitizeForLog(params.botIdentity) : "";
  const identitySuffix = safeIdentity ? ` as ${safeIdentity}` : "";
  return params.gatewayReady
    ? `logged in to discord${identitySuffix}`
    : `discord client initialized${identitySuffix}; awaiting gateway readiness`;
}

Alternatively, expose and reuse the repo's existing terminal-safe sanitizer (src/terminal/safe-text.ts) so all user-controlled strings logged to the terminal are normalized consistently.


Analyzed PR: #51425 at commit 390986d

Last updated on: 2026-03-21T05:15:14Z

JohnJAS pushed a commit to JohnJAS/openclaw that referenced this pull request Mar 22, 2026
Merged via squash.

Prepared head SHA: 390986d
Co-authored-by: scoootscooob <[email protected]>
Co-authored-by: scoootscooob <[email protected]>
Reviewed-by: @scoootscooob
pholpaphankorn pushed a commit to pholpaphankorn/openclaw that referenced this pull request Mar 22, 2026
Merged via squash.

Prepared head SHA: 390986d
Co-authored-by: scoootscooob <[email protected]>
Co-authored-by: scoootscooob <[email protected]>
Reviewed-by: @scoootscooob
frankekn pushed a commit to artwalker/openclaw that referenced this pull request Mar 23, 2026
Merged via squash.

Prepared head SHA: 390986d
Co-authored-by: scoootscooob <[email protected]>
Co-authored-by: scoootscooob <[email protected]>
Reviewed-by: @scoootscooob
furaul pushed a commit to furaul/openclaw that referenced this pull request Mar 24, 2026
Merged via squash.

Prepared head SHA: 390986d
Co-authored-by: scoootscooob <[email protected]>
Co-authored-by: scoootscooob <[email protected]>
Reviewed-by: @scoootscooob
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: discord Channel integration: discord maintainer Maintainer-authored PR size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant