Skip to content

fix(systemd): handle missing DBUS env vars gracefully in isSystemdServiceEnabled#7730

Closed
briancolinger wants to merge 1 commit intoopenclaw:mainfrom
briancolinger:fix/ubuntu-systemd-dbus
Closed

fix(systemd): handle missing DBUS env vars gracefully in isSystemdServiceEnabled#7730
briancolinger wants to merge 1 commit intoopenclaw:mainfrom
briancolinger:fix/ubuntu-systemd-dbus

Conversation

@briancolinger
Copy link
Copy Markdown

@briancolinger briancolinger commented Feb 3, 2026

Summary

When $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR are not set (SSH sessions, WSL, certain terminals), systemctl --user commands fail with:

Failed to connect to bus: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined

The isSystemdUserServiceAvailable function already handled this error gracefully by returning false. However, isSystemdServiceEnabled was calling assertSystemdAvailable() directly, which throws on this error.

This caused the onboarding wizard to show error messages like:

Gateway service check failed: Error: systemctl --user unavailable: Failed to connect to bus: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined

Fix

Wrap the assertSystemdAvailable() call in isSystemdServiceEnabled with try-catch and return false when it throws. This is semantically correct — if systemd user services are unavailable, no service can be enabled.

Testing

Added 3 test cases to systemd-availability.test.ts:

  • Returns false when DBUS env vars are missing
  • Returns true when service is enabled
  • Returns false when service is not enabled

All existing tests continue to pass.

Fixes #1818

Greptile Overview

Greptile Summary

This PR makes isSystemdServiceEnabled resilient to environments where systemctl --user can’t connect to the user bus (common in SSH/WSL when DBUS env vars aren’t set). The core change wraps assertSystemdAvailable() in a try/catch and returns false on failure, aligning behavior with isSystemdUserServiceAvailable().

It also adds Vitest coverage for the new behavior, plus basic enabled/disabled cases, to prevent regressions in the onboarding wizard’s systemd checks.

Confidence Score: 4/5

  • This PR is likely safe to merge and improves robustness for common non-GUI Linux environments.
  • The change is small, localized, and covered by new unit tests. Main remaining concern is that the new catch-all could hide unrelated assertSystemdAvailable() failures by silently returning false, which may reduce diagnosability in unexpected error scenarios.
  • src/daemon/systemd.ts (catch-all error handling semantics)

(5/5) You can turn off certain types of comments like style here!

@openclaw-barnacle openclaw-barnacle bot added the gateway Gateway runtime label Feb 3, 2026
Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

2 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

Comment on lines +329 to +336
try {
await assertSystemdAvailable();
} catch {
// If systemd user services are unavailable (e.g., missing DBUS_SESSION_BUS_ADDRESS
// or XDG_RUNTIME_DIR in SSH sessions, WSL, or certain terminals), the service
// cannot be enabled.
return false;
}
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] Catch-all hides unexpected assertSystemdAvailable failures

isSystemdServiceEnabled now returns false for any error from assertSystemdAvailable(), which includes cases beyond missing DBUS env vars (e.g., permission issues, transient exec errors). That can mask real problems and make debugging harder.

Consider narrowing this to known “systemd user services unavailable” errors (similar to isSystemdUserServiceAvailable()’s failed to connect / not been booted checks) or at least logging/including the error detail somewhere before returning false.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/daemon/systemd.ts
Line: 329:336

Comment:
[P2] Catch-all hides unexpected `assertSystemdAvailable` failures

`isSystemdServiceEnabled` now returns `false` for *any* error from `assertSystemdAvailable()`, which includes cases beyond missing DBUS env vars (e.g., permission issues, transient exec errors). That can mask real problems and make debugging harder.

Consider narrowing this to known “systemd user services unavailable” errors (similar to `isSystemdUserServiceAvailable()`’s `failed to connect` / `not been booted` checks) or at least logging/including the error detail somewhere before returning `false`.

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

Comment on lines +62 to +70
execFileMock.mockImplementation((_cmd, args, _opts, cb) => {
callCount++;
if (callCount === 1) {
// First call: systemctl --user status (availability check)
cb(null, "", "");
} else {
// Second call: systemctl --user is-enabled
cb(null, "enabled", "");
}
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.

[P3] Unused args parameter in mock callback

In the execFileMock implementations, args is declared but never used (e.g. here and again in the “not enabled” test). This can trigger lint warnings and makes it look like the test is asserting on args when it isn’t.

You can rename it to _args (or remove it) to match the other tests’ style.

Also appears in: src/daemon/systemd-availability.test.ts:77-87.

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!

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/daemon/systemd-availability.test.ts
Line: 62:70

Comment:
[P3] Unused `args` parameter in mock callback

In the `execFileMock` implementations, `args` is declared but never used (e.g. here and again in the “not enabled” test). This can trigger lint warnings and makes it look like the test is asserting on args when it isn’t.

You can rename it to `_args` (or remove it) to match the other tests’ style.

Also appears in: src/daemon/systemd-availability.test.ts:77-87.

<sub>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!</sub>

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

@openclaw-barnacle openclaw-barnacle bot added the docs Improvements or additions to documentation label Feb 3, 2026
…viceEnabled

When $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR are not set (SSH
sessions, WSL, certain terminals), systemctl --user commands fail. The
isSystemdUserServiceAvailable function already handled this gracefully,
but isSystemdServiceEnabled threw via assertSystemdAvailable.

Now isSystemdServiceEnabled catches the error and returns false,
consistent with the semantics that if systemd user services are
unavailable, no service can be enabled.

Fixes #1818
@briancolinger briancolinger force-pushed the fix/ubuntu-systemd-dbus branch from 4dbace6 to 4230675 Compare February 9, 2026 18:29
@openclaw-barnacle openclaw-barnacle bot removed the docs Improvements or additions to documentation label Feb 9, 2026
bob10042 pushed a commit to bob10042/openclaw that referenced this pull request Feb 14, 2026
- Update all documentation URLs from docs.anthropic.com to docs.claude.com to avoid redirects
- Change Getting Started Guide URL from /getting-started to /quickstart path
- Remove Discussions link as GitHub Discussions are not enabled for this repository

Fixes openclaw#7730
@briancolinger briancolinger closed this by deleting the head repository Feb 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gateway Gateway runtime

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Onboarding wizard does not install Systemd service on Ubuntu 22.04

1 participant