Skip to content

Typecheck depends on ambient parent openclaw SDK types #2729

Description

@zsimovanforgeops

Summary

bunx tsc --noEmit can fail on a clean v0.42.58.0 checkout depending on an undeclared openclaw package found in a parent node_modules directory.

The real plugin-load E2E test dynamically imports openclaw/plugin-sdk, but TypeScript still resolves and type-checks that bare module. The @ts-ignore is attached to the import line; the actual error occurs on the following property-access line.

Affected version

  • v0.42.58.0
  • commit a25209bbb2bacf1b88e06fd5282b27f1bf4a3e7a

Reproduction

On a clean checkout where a parent directory contains an OpenClaw SDK version without a typed registerContextEngine export:

bun install --frozen-lockfile
bunx tsc --noEmit

Observed:

test/e2e/openclaw-plugin-load-real.test.ts(281,37): error TS2339:
Property 'registerContextEngine' does not exist on type
'typeof import(".../node_modules/openclaw/dist/plugin-sdk/index")'.

package.json declares OpenClaw compatibility metadata but does not declare openclaw as a dependency or devDependency. Bun/TypeScript therefore walks upward and compiles against ambient parent state.

Relevant code:

// @ts-ignore — bare specifier resolution depends on node_modules.
const sdk = await import('openclaw/plugin-sdk');
registerContextEngine = sdk.registerContextEngine;

The ignore does not cover the failing property access.

Expected behavior

A clean checkout's typecheck should not depend on whatever OpenClaw SDK happens to be installed in a parent directory. The runtime compatibility test may still dynamically probe the installed CLI/SDK, but compile-time verification should remain hermetic.

Possible fix

Treat the dynamically imported SDK as an unknown runtime object and validate the optional property structurally, for example with an explicit unknown cast and a local interface/type guard. This keeps the runtime test's intent without binding repository typecheck to an undeclared ambient package version.

Baseline proof

The failure was reproduced after stashing all local changes and running bunx tsc --noEmit against untouched v0.42.58.0. Restoring the unrelated provider patch produced the identical single failure.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions