Skip to content

fix: an opencode session outside lich starts again - #16

Merged
omartelo merged 2 commits into
mainfrom
fix/opencode-single-export
Aug 12, 2026
Merged

omartelo merged 2 commits into
mainfrom
fix/opencode-single-export

Conversation

@omartelo

Copy link
Copy Markdown
Collaborator

Running opencode in a plain terminal with the plugin installed died at
startup:

Error: Unexpected server error. Check server logs for details.

The server log named the cause twice:

level=ERROR message="plugin config hook failed" error="null is not an object (evaluating 'N.config')"
level=ERROR message="Event listener failed" eventType=session.created cause="Die(TypeError: null is not an object (evaluating 'V.event'))"

Root cause

opencode loads every export of a plugin module as a plugin, not just the one
that looks like one. opencode/lich.js exported lichTools beside
LichPlugin, so opencode called it with the plugin input too — $ got the
input object, helper was undefined — and outside lich the
LICH_PORT/LICH_TOKEN/LICH_SESSION_ID guard returned null. opencode then
read hook keys off that null.

Inside lich it went unnoticed: the same call returned the tools object, whose
unknown keys opencode ignores. Only a bare terminal ever saw it.

Fix

The export existed for one reason — the suite has to inject the tool package,
because opencode resolves it from its own plugin dependencies and a checkout of
this repository has none. That seam moves onto LichPlugin's second argument,
which opencode never passes. The module is back to one export.

Test plan

  • node --test tests/*.test.mjs — 127 pass
  • New test loads the module the way opencode does: no lich environment,
    every export called with a plugin input, each result asserted to be a
    hooks object whose keys can be read. It fails on the export this PR
    removes (verified by re-adding the keyword).
  • Isolated rig (own XDG_CONFIG_HOME/XDG_DATA_HOME, opencode 1.18.16):
    reproduced upstream by @mellow-badger — only the export keyword differs
    between the crashing and the working run.

Also cuts the release: [Unreleased] moves under v0.9.2 and both manifests
align with the tag. lich installs the module at the latest release's tag, so
the fix only reaches sessions once that release exists — tag and release to
follow the merge.

Running opencode outside lich with the plugin installed failed at
startup with `Error: Unexpected server error`, and the server log named
the cause twice: `plugin config hook failed` on `null is not an object
(evaluating 'N.config')`, then the same on the session.created listener.

opencode loads every export of a plugin module as a plugin, not just the
one that looks like one. It called `lichTools` with the plugin input,
which made `$` the input object and left `helper` undefined, and outside
lich the LICH_PORT/LICH_TOKEN/LICH_SESSION_ID guard returned `null` — so
opencode went looking for hook keys on `null` and died. Inside lich the
same call returned the tools object, whose unknown keys opencode ignores,
which is why only a bare terminal ever saw it.

The export existed for one reason: the suite has to inject the tool
package, because opencode resolves it from its own plugin dependencies
and a checkout of this repository has none. That seam moves onto
`LichPlugin`'s second argument instead. opencode calls a plugin with a
single argument, so the parameter is invisible to it, and the module is
back to one export.

The regression test loads the module the way opencode does: with no lich
environment, it calls every export with a plugin input and asserts each
one hands back a hooks object whose keys can be read. It fails on the
export this commit removes.
Moves the [Unreleased] entry under a v0.9.2 heading, refreshes the
compare links, and aligns the version in both manifests with the tag.

The release is what carries the fix: lich installs opencode's client by
fetching the module at the latest release's tag, so every opencode
session started outside lich keeps dying at startup until this one
exists.
@omartelo
omartelo merged commit 06ee048 into main Aug 12, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant