openclaw - ✅(Solved) Fix [Bug]: api.runtime.version returns 'unknown' for plugins in npm-installed OpenClaw [3 pull requests, 3 comments, 4 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#51494Fetched 2026-04-08 01:10:27
View on GitHub
Comments
3
Participants
4
Timeline
7
Reactions
0
Author
Timeline (top)
commented ×3cross-referenced ×3referenced ×1

api.runtime.version (exposed to plugins via createPluginRuntime()) always returns "unknown" when OpenClaw is installed via npm. The resolveVersion() function in src/plugins/runtime/index.ts uses a hardcoded relative path "../../../package.json" that only works in the source tree, not in the bundled dist/ output.

Root Cause

Root cause: resolveVersion() in src/plugins/runtime/index.ts (line 25) uses:

Fix Action

Fix / Workaround

This was discovered while developing the CoClaw channel plugin. We've added a workaround on our side: when api.runtime.version is falsy or "unknown", we simply omit the field from our RPC response rather than surfacing the incorrect value.

PR fix notes

PR #51520: fix(plugins): use VERSION from version.ts in createPluginRuntime

Description (problem / solution / changelog)

Problem

api.runtime.version always returns "unknown" for plugins in npm-installed OpenClaw (fixes #51494).

The root cause is the local resolveVersion() function in src/plugins/runtime/index.ts, which uses a hardcoded relative path:

const pkg = require("../../../package.json") as { version?: string };

This path is based on the source directory depth (src/plugins/runtime/ → 3 levels up = repo root). After bundling, all chunks are flattened into dist/, so the path overshoots the package boundary entirely and the require call throws, causing the catch block to return "unknown".

Fix

Remove the local resolveVersion() helper and import the already-resolved VERSION constant from src/version.ts directly:

import { VERSION } from "../../version.js";
// ...
version: VERSION,

src/version.ts already solved this exact problem via a candidate-list strategy with package name validation (requirePackageName: true), and also handles bundled/embedded builds via the __OPENCLAW_VERSION__ define or OPENCLAW_BUNDLED_VERSION env var. Using it as the single source of truth eliminates the redundant, broken path resolution in the plugin runtime.

Changes

  • Remove import { createRequire } from "node:module" (no longer needed)
  • Remove cachedVersion module-level variable
  • Remove resolveVersion() function
  • Add import { VERSION } from "../../version.js"
  • Replace version: resolveVersion() with version: VERSION

Testing

After this change, api.runtime.version in the plugin runtime will return the same value as openclaw --version, consistent across source, npm-installed, and bundled environments.

Changed files

  • src/plugins/runtime/index.ts (modified, +3/-20)

PR #51529: fix(plugins/runtime): fix api.runtime.version in bundled and npm installs

Description (problem / solution / changelog)

TL;DR

api.runtime.version was broken for bundled/npm installs because plugin runtime used a source-tree-relative package.json path. This PR switches it to the shared version resolver, keeps the "unknown" fallback behavior, and adds regression coverage.

Summary

  • Problem: api.runtime.version returned "unknown" for plugins in npm-installed/bundled OpenClaw because the plugin runtime resolved ../../../package.json relative to a bundled root chunk.
  • Why it matters: plugins that gate behavior on the host OpenClaw version could not reliably detect compatibility and had to special-case "unknown".
  • What changed: the plugin runtime now uses the shared VERSION resolver from src/version.ts, and regression tests cover both the shared dist/*.js chunk layout and plugin-runtime alignment.
  • What did NOT change (scope boundary): no gateway routing, auth, persistence, channel delivery, or plugin loader behavior changed.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • 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

  • Closes #51494
  • Related #None

User-visible / Behavior Changes

Plugins that read api.runtime.version now receive the actual OpenClaw version in npm-installed/bundled environments instead of "unknown".

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

Repro + Verification

Environment

  • OS: macOS host
  • Runtime/container: Node 22 / pnpm
  • Model/provider: N/A
  • Integration/channel (if any): plugin runtime
  • Relevant config (redacted): N/A

Steps

  1. Build or inspect the bundled OpenClaw runtime where plugin runtime code is emitted into a root dist/*.js chunk.
  2. Read api.runtime.version from createPluginRuntime().
  3. Observe the old runtime resolves ../../../package.json from the bundled chunk and returns "unknown".

Expected

  • api.runtime.version matches the installed OpenClaw version.

Actual

  • api.runtime.version returned "unknown" before this fix.

Evidence

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

Human Verification (required)

  • Verified scenarios: reproduced the old bundled-path failure mode; ran targeted regression tests; built the repo; imported dist/plugins/runtime/index.js and confirmed the built artifact returns the real package version.
  • Edge cases checked: shared dist/chunk.js root-chunk layout; plugin runtime fallback still normalizes unusable versions to "unknown".
  • What you did not verify: third-party plugin end-to-end behavior in a separate npm-global install.

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.

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly: revert this PR.
  • Files/config to restore: src/plugins/runtime/index.ts
  • Known bad symptoms reviewers should watch for: plugins reporting "unknown" again for api.runtime.version in bundled/npm installs.

Risks and Mitigations

  • Risk: plugin runtime version now depends on the shared resolver path.
  • Mitigation: added regression coverage for both the shared root-chunk bundle layout and the plugin runtime contract.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/plugins/runtime/index.test.ts (modified, +6/-0)
  • src/plugins/runtime/index.ts (modified, +4/-10)
  • src/version.test.ts (modified, +9/-0)

PR #25: fix: migrate to plugin-sdk subpath imports for OpenClaw 2026.3.24+

Description (problem / solution / changelog)

Summary

  • Migrate all src/ imports from the monolithic openclaw/plugin-sdk entrypoint to the new subpath exports introduced in OpenClaw 2026.3.24+
  • stringEnum, optionalStringEnum, jsonResult now import from openclaw/plugin-sdk/agent-runtime
  • formatErrorMessage now imports from openclaw/plugin-sdk/error-runtime
  • safeParseJson now imports from openclaw/plugin-sdk/text-runtime

Fixes #24

Test plan

  • Verify the plugin builds successfully with npm run build
  • Confirm all tool handlers still function correctly against a Linear workspace
  • Validate webhook handling and work queue processing remain operational

🤖 Generated with Claude Code

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

Summary by CodeRabbit

  • Chores
    • Reorganized internal module dependencies to improve code maintainability and separation of concerns across the plugin.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Changed files

  • src/index.ts (modified, +1/-1)
  • src/tools/linear-comment-tool.ts (modified, +2/-1)
  • src/tools/linear-issue-tool.ts (modified, +2/-1)
  • src/tools/linear-project-tool.ts (modified, +2/-1)
  • src/tools/linear-relation-tool.ts (modified, +2/-1)
  • src/tools/linear-team-tool.ts (modified, +2/-1)
  • src/tools/queue-tool.ts (modified, +1/-1)
  • src/webhook-handler.ts (modified, +1/-1)
  • src/work-queue.ts (modified, +1/-1)

Code Example

const require = createRequire(import.meta.url);
const pkg = require("../../../package.json");

---

const candidates = ["../package.json", "../../package.json", "../../../package.json", "./package.json"];
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug

Summary

api.runtime.version (exposed to plugins via createPluginRuntime()) always returns "unknown" when OpenClaw is installed via npm. The resolveVersion() function in src/plugins/runtime/index.ts uses a hardcoded relative path "../../../package.json" that only works in the source tree, not in the bundled dist/ output.

Steps to reproduce

  1. Install OpenClaw globally via npm (npm install -g openclaw)
  2. Create or install a plugin that reads api.runtime.version in its register(api) function
  3. Observe that api.runtime.version returns "unknown" instead of the actual version

Expected behavior

api.runtime.version should return the actual OpenClaw version string (e.g., "2026.3.13"), consistent with openclaw --version output.

Actual behavior

api.runtime.version returns "unknown".

Root cause: resolveVersion() in src/plugins/runtime/index.ts (line 25) uses:

const require = createRequire(import.meta.url);
const pkg = require("../../../package.json");

The path "../../../package.json" is based on the source directory depth (src/plugins/runtime/ → 3 levels up to repo root). After bundling, all chunks are flattened into dist/, so import.meta.url points to dist/<chunk>.js. From there, ../../../package.json resolves 3 levels above dist/, which overshoots the package boundary entirely. The require call throws, and the catch block returns "unknown".

Already fixed in src/version.ts

The same class of bug was already addressed in src/version.ts (the VERSION constant used by gateway/CLI). That implementation uses a candidate list with package name validation:

const candidates = ["../package.json", "../../package.json", "../../../package.json", "./package.json"];

Each candidate is checked for name === "openclaw" before accepting. This approach correctly resolves ../package.json (one level up from dist/) in npm-installed environments.

Suggested fix

Apply the same candidate-list strategy from src/version.ts to src/plugins/runtime/index.ts, or have createPluginRuntime() reference the already-resolved VERSION constant from src/version.ts directly.

OpenClaw version

2026.3.13

Operating system

Linux (WSL2, kernel 6.6.87.2-microsoft-standard-WSL2)

Model

N/A (not model-related)

Provider / routing chain

N/A

Install method

npm global

Additional information

This was discovered while developing the CoClaw channel plugin. We've added a workaround on our side: when api.runtime.version is falsy or "unknown", we simply omit the field from our RPC response rather than surfacing the incorrect value.


Reported by the CoClaw team. This issue was discovered while developing @coclaw/openclaw-coclaw, a CoClaw channel plugin for OpenClaw.

extent analysis

Fix Plan

To fix the issue, we will apply the candidate-list strategy from src/version.ts to src/plugins/runtime/index.ts. Here are the steps:

  • Modify src/plugins/runtime/index.ts to use a candidate list for resolving package.json:
const candidates = ["../package.json", "../../package.json", "../../../package.json", "./package.json"];
const require = createRequire(import.meta.url);
let pkg;
for (const candidate of candidates) {
  try {
    pkg = require(candidate);
    if (pkg.name === "openclaw") {
      break;
    }
  } catch (e) {
    // continue to next candidate
  }
}
if (!pkg || pkg.name !== "openclaw") {
  // handle error or return "unknown"
}
  • Alternatively, we can have createPluginRuntime() reference the already-resolved VERSION constant from src/version.ts directly:
import { VERSION } from '../version';
// ...
api.runtime.version = VERSION;

Verification

To verify the fix, follow these steps:

  • Install OpenClaw globally via npm (npm install -g openclaw)
  • Create or install a plugin that reads api.runtime.version in its register(api) function
  • Check that api.runtime.version returns the actual OpenClaw version string (e.g., "2026.3.13")

Extra Tips

  • Make sure to test the fix in different environments, including npm-installed and source tree environments.
  • Consider adding a test case to ensure that api.runtime.version returns the correct value in different scenarios.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

api.runtime.version should return the actual OpenClaw version string (e.g., "2026.3.13"), consistent with openclaw --version output.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix [Bug]: api.runtime.version returns 'unknown' for plugins in npm-installed OpenClaw [3 pull requests, 3 comments, 4 participants]