[BUG]: Plugin tool context.metadata() is never executed, so live updates are dropped

Open Beginner friendly
#50,313 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
88/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
typescript
Domain
backend

Research direction

Start in packages/opencode/src/tool/registry.ts at fromPlugin(), comparing the existing ask() bridge with the metadata() handling. Reproduce the five-second plugin tool case described in the issue, then run packages/opencode/test/tool/registry.test.ts and confirm live metadata appears during execution rather than only in the final result.

Written by the indexing model from the issue text.

Description

Description

Plugin tools cannot publish metadata while they are still running. A call to context.metadata(...) from inside a custom tool has no effect, and the metadata only appears once the tool finishes and returns it as part of its final result.

The cause is a missing bridge in fromPlugin(). The host tool context declares metadata() as Effect-returning:

https://github.com/anomalyco/opencode/blob/cf494c2029d4334dfe6defc31209341ca97c2e94/packages/opencode/src/tool/tool.ts#L44

while the public plugin API declares it as a plain synchronous void call:

https://github.com/anomalyco/opencode/blob/cf494c2029d4334dfe6defc31209341ca97c2e94/packages/plugin/src/tool.ts#L18

fromPlugin() bridges ask() but spreads metadata() straight through, so the plugin gets handed an Effect that nobody runs:

https://github.com/anomalyco/opencode/blob/cf494c2029d4334dfe6defc31209341ca97c2e94/packages/opencode/src/tool/registry.ts#L147-L153

This breaks anything that relies on live tool metadata. The case I hit is a foreground task plugin that publishes its child sessionId before starting the child prompt: the client cannot subscribe to the child session while the task runs, and the id only shows up once the task is already over.

The fix is one line, bridging metadata() the same way ask() already is, forked rather than awaited because the public signature is synchronous:

metadata: (input) => {
  bridge.fork(toolCtx.metadata(input))
},

#47486 has that plus a regression test in packages/opencode/test/tool/registry.test.ts that fails on dev and passes with the fix. wulart independently reproduced the bug and confirmed the patch against 9a53565.

Previously reported in #37877, which the stale bot closed after 60 days of inactivity with a note to open a new one if it is still relevant. It was never fixed and still reproduces on dev at cf494c2029d4334dfe6defc31209341ca97c2e94. #12527 is related but different, it fixed metadata preservation in the completed result rather than live calls.

Plugins

Any custom tool under .opencode/tools/ that calls context.metadata() mid-execution.

OpenCode version

1.18.31, and current dev.

Steps to reproduce

Drop this in .opencode/tools/progress.ts:

import { tool } from "@opencode-ai/plugin"

export default tool({
  description: "Test live plugin metadata",
  args: {},
  async execute(_input, context) {
    context.metadata({ title: "Running", metadata: { phase: "running" } })
    await new Promise((resolve) => setTimeout(resolve, 5000))
    return { title: "Done", metadata: { phase: "done" }, output: "done" }
  },
})
  1. Invoke the tool.
  2. Inspect the ToolPart during the five second delay. Expected: title Running and phase: running. Actual: still pending, no metadata.
  3. Wait for completion. The final returned title and metadata appear normally.
Screenshot and/or share link

Not applicable, this is a server-side plugin bridge.

Operating System

Linux

Terminal

N/A

Dominant language
TypeScript
Stars
209k
Forks
27.5k
Avg merge
7h 20m
Merged PRs (30d)
358

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from anomalyco/opencode

All issues in anomalyco/opencode

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.