[BUG]: client.app is undefined when passed to plugins, causing crashes in plugin logging #3662

Open
opened 2026-02-16 17:41:02 -05:00 by yindo · 1 comment
Owner

Originally created by @shekohex on GitHub (Dec 19, 2025).

Originally assigned to: @rekram1-node on GitHub.

Description

When a plugin attempts to use client.app.log() to write to server logs, it crashes with TypeError: undefined is not an object because client.app is undefined, even though the SDK types declare it as a required (non-optional) property.

Environment

Component Version
OpenCode 1.0.167
@opencode-ai/plugin ^1.0.169
@opencode-ai/sdk ^1.0.169
OS Linux (glibc)
Runtime Bun 1.3.4

Error

TypeError: undefined is not an object (evaluating '_client.app.log')
    at log (logger.ts:64:15)
    at prepareAntigravityRequest (request.ts:329:9)
    at tryEndpointFallbacks (fetch-wrapper.ts:522:83)

Analysis

SDK Type Declaration

In @opencode-ai/sdk, the OpencodeClient class declares app as a required property:

// sdk.gen.d.ts
export declare class OpencodeClient extends _HeyApiClient {
    // ...
    app: App;  // Non-optional
    // ...
}

SDK Implementation

The implementation shows app is initialized as a class field:

// sdk.gen.js
export class OpencodeClient extends _HeyApiClient {
    // ...
    app = new App({ client: this._client });
    // ...
}

Expected Behavior

When a plugin receives client: ReturnType<typeof createOpencodeClient> via PluginInput, the client.app property should always be defined and usable.

Actual Behavior

At runtime, client.app is undefined. The JSC error message format confirms this:

  • Error says evaluating '_client.app.log' (meaning _client.app is undefined)
  • If _client itself was undefined, error would say evaluating '_client.app'

Reproduction

  1. Create a plugin that calls client.app.log():

    export const MyPlugin = async ({ client }: PluginContext) => {
      // This crashes:
      await client.app.log({ body: { message: "test" } });
    };
    
  2. The crash occurs during normal plugin operation, particularly when:

    • Plugin is loaded and initialized
    • First message works
    • Second message triggers the crash (during API request handling)

Questions

  1. Is the client object passed to plugins intended to be a full OpencodeClient instance?
  2. Are sub-clients like app, tui, auth lazily initialized or always available?
  3. Is there a specific lifecycle point after which client.app becomes available?

Workaround

Plugins can use optional chaining as a defensive measure:

if (client?.app?.log) {
  client.app.log({...});
}

However, this shouldn't be necessary if the types declare app as required.

Related

Originally created by @shekohex on GitHub (Dec 19, 2025). Originally assigned to: @rekram1-node on GitHub. ## Description When a plugin attempts to use `client.app.log()` to write to server logs, it crashes with `TypeError: undefined is not an object` because `client.app` is `undefined`, even though the SDK types declare it as a required (non-optional) property. ## Environment | Component | Version | |:---|:---| | **OpenCode** | 1.0.167 | | **@opencode-ai/plugin** | ^1.0.169 | | **@opencode-ai/sdk** | ^1.0.169 | | **OS** | Linux (glibc) | | **Runtime** | Bun 1.3.4 | ## Error ``` TypeError: undefined is not an object (evaluating '_client.app.log') at log (logger.ts:64:15) at prepareAntigravityRequest (request.ts:329:9) at tryEndpointFallbacks (fetch-wrapper.ts:522:83) ``` ## Analysis ### SDK Type Declaration In `@opencode-ai/sdk`, the `OpencodeClient` class declares `app` as a required property: ```typescript // sdk.gen.d.ts export declare class OpencodeClient extends _HeyApiClient { // ... app: App; // Non-optional // ... } ``` ### SDK Implementation The implementation shows `app` is initialized as a class field: ```javascript // sdk.gen.js export class OpencodeClient extends _HeyApiClient { // ... app = new App({ client: this._client }); // ... } ``` ### Expected Behavior When a plugin receives `client: ReturnType<typeof createOpencodeClient>` via `PluginInput`, the `client.app` property should always be defined and usable. ### Actual Behavior At runtime, `client.app` is `undefined`. The JSC error message format confirms this: - Error says `evaluating '_client.app.log'` (meaning `_client.app` is undefined) - If `_client` itself was undefined, error would say `evaluating '_client.app'` ## Reproduction 1. Create a plugin that calls `client.app.log()`: ```typescript export const MyPlugin = async ({ client }: PluginContext) => { // This crashes: await client.app.log({ body: { message: "test" } }); }; ``` 2. The crash occurs during normal plugin operation, particularly when: - Plugin is loaded and initialized - First message works - Second message triggers the crash (during API request handling) ## Questions 1. Is the `client` object passed to plugins intended to be a full `OpencodeClient` instance? 2. Are sub-clients like `app`, `tui`, `auth` lazily initialized or always available? 3. Is there a specific lifecycle point after which `client.app` becomes available? ## Workaround Plugins can use optional chaining as a defensive measure: ```typescript if (client?.app?.log) { client.app.log({...}); } ``` However, this shouldn't be necessary if the types declare `app` as required. ## Related - Plugin experiencing this issue: [opencode-google-antigravity-auth](https://github.com/shekohex/opencode-google-antigravity-auth) - Original bug report: https://github.com/shekohex/opencode-google-antigravity-auth/issues/8
Author
Owner

@github-actions[bot] commented on GitHub (Dec 19, 2025):

This issue might be a duplicate of existing issues. Please check:

  • #5449: client.session.summarize hangs forever in Plugin - indicates plugin client methods may not be properly initialized

Feel free to ignore if this doesn't address your specific case.

@github-actions[bot] commented on GitHub (Dec 19, 2025): This issue might be a duplicate of existing issues. Please check: - #5449: `client.session.summarize` hangs forever in Plugin - indicates plugin client methods may not be properly initialized Feel free to ignore if this doesn't address your specific case.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#3662