Summary
opencode 1.14.49 and 1.14.50 crash during SessionPrompt.resolveTools with TypeError: Object.entries requires that input parameter not be null or undefined when a project's .opencode/tool/index.ts (or any user-config tool file) export … from's another module.
End-user symptom: opencode run "<anything>" returns:
Error: {
"name": "UnknownError",
"data": {
"message": "Unexpected server error. Check server logs for details."
}
}
…on the very first prompt — the LLM is never reached. The only way to see the underlying cause is opencode --print-logs.
Stack trace
ERROR service=server error=Object.entries requires that input parameter not be null or undefined cause=TypeError: Object.entries requires that input parameter not be null or undefined
at entries (unknown)
at _ (/$bunfs/root/chunk-82efwr7g.js:1799:849)
at <anonymous> (/$bunfs/root/chunk-82efwr7g.js:1799:2033)
at ToolRegistry.state (/$bunfs/root/chunk-djqek613.js:675:17303)
at ToolRegistry.state (definition) (/$bunfs/root/chunk-82efwr7g.js:1799:766)
at ToolRegistry.all (/$bunfs/root/chunk-82efwr7g.js:1802:62)
at ToolRegistry.all (definition) (/$bunfs/root/chunk-82efwr7g.js:1799:2850)
at ToolRegistry.tools (/$bunfs/root/chunk-82efwr7g.js:1884:897)
at ToolRegistry.tools (definition) (/$bunfs/root/chunk-82efwr7g.js:1802:12)
at SessionPrompt.resolveTools (/$bunfs/root/chunk-82efwr7g.js:1890:3276)
at SessionPrompt.resolveTools (definition) (/$bunfs/root/chunk-82efwr7g.js:1884:79)
at SessionPrompt.run (/$bunfs/root/chunk-82efwr7g.js:1891:1368)
Reproducer
A widely-used real-world layout that trips this is the OpenAgentsControl .opencode/tool/index.ts barrel:
// .opencode/tool/index.ts
export {
generate, edit, analyze,
generateImage, editImage, analyzeImage,
default as gemini
} from "./gemini"
export {
loadEnvVariables, getEnvVariable,
getRequiredEnvVariable, getRequiredEnvVariables,
getApiKey, type EnvLoaderConfig
} from "./env"
Where ./gemini exports valid tool({...}) definitions and ./env exports plain helpers. Steps:
- Have any project (or
~/.config/opencode/) with a .opencode/tool/index.ts that does export … from "./<other-module>".
opencode run "ping".
- Observe
Unexpected server error. Run with --print-logs to see the trace above.
Bisect: it's the re-export, not the helpers
I tried trimming the barrel down to only valid tool() re-exports (dropping the env helper exports):
export { generate, edit, analyze, generateImage, editImage, analyzeImage, default as gemini } from "./gemini"
Still crashes. The scanner appears to fail on any export … from re-export from tool/index.ts, even when the re-exported items are valid tool() definitions.
Workaround: the file has to be empty (or removed):
// .opencode/tool/index.ts
export {}
After that, opencode run "ping" works and the per-subdirectory tools (./gemini/index.ts, etc.) are still auto-discovered correctly.
Regression
opencode 1.14.48 silently tolerated the same barrel and worked fine. The break appears in 1.14.49 and is not fixed in 1.14.50 (its changelog has nothing about the tool registry).
git diff v1.14.48..v1.14.50 touched packages/llm/src/tool.ts, packages/llm/src/tool-runtime.ts, and packages/core/src/session-prompt.ts, but I couldn't pinpoint the exact site that introduced the strict Object.entries call. The minified bundle path chunk-djqek613.js:675:17303 → ToolRegistry.state is where the unsafe Object.entries lives.
Environment
- opencode 1.14.49 (regression introduced) and 1.14.50 (still broken)
- macOS 25.5.0 (Darwin), Apple Silicon
- Installed via
curl -fsSL https://opencode.ai/install | bash
Suggested fix
ToolRegistry.state() should treat a tool module that re-exports from sibling modules as either:
- correctly resolved (follow the re-export and register the underlying tool), or
- gracefully ignored (it's a barrel, not a tool definition itself),
instead of calling Object.entries() on whatever non-tool shape it ends up with. The 1.14.48 behavior of "silently tolerate barrels" is the user-friendly default; even rejecting them with a clear error message would be much better than the current generic Unexpected server error.
Workaround for users
Until this is fixed, replace any re-exporting tool/index.ts with:
// .opencode/tool/index.ts
export {}
And import tools directly from their subdirectories (./gemini, ./template, etc.) instead of through the barrel.
Summary
opencode1.14.49 and 1.14.50 crash duringSessionPrompt.resolveToolswithTypeError: Object.entries requires that input parameter not be null or undefinedwhen a project's.opencode/tool/index.ts(or any user-config tool file)export … from's another module.End-user symptom:
opencode run "<anything>"returns:…on the very first prompt — the LLM is never reached. The only way to see the underlying cause is
opencode --print-logs.Stack trace
Reproducer
A widely-used real-world layout that trips this is the OpenAgentsControl
.opencode/tool/index.tsbarrel:Where
./geminiexports validtool({...})definitions and./envexports plain helpers. Steps:~/.config/opencode/) with a.opencode/tool/index.tsthat doesexport … from "./<other-module>".opencode run "ping".Unexpected server error. Run with--print-logsto see the trace above.Bisect: it's the re-export, not the helpers
I tried trimming the barrel down to only valid
tool()re-exports (dropping the env helper exports):Still crashes. The scanner appears to fail on any
export … fromre-export fromtool/index.ts, even when the re-exported items are validtool()definitions.Workaround: the file has to be empty (or removed):
After that,
opencode run "ping"works and the per-subdirectory tools (./gemini/index.ts, etc.) are still auto-discovered correctly.Regression
opencode 1.14.48silently tolerated the same barrel and worked fine. The break appears in 1.14.49 and is not fixed in 1.14.50 (its changelog has nothing about the tool registry).git diff v1.14.48..v1.14.50touchedpackages/llm/src/tool.ts,packages/llm/src/tool-runtime.ts, andpackages/core/src/session-prompt.ts, but I couldn't pinpoint the exact site that introduced the strictObject.entriescall. The minified bundle pathchunk-djqek613.js:675:17303 → ToolRegistry.stateis where the unsafeObject.entrieslives.Environment
curl -fsSL https://opencode.ai/install | bashSuggested fix
ToolRegistry.state()should treat a tool module that re-exports from sibling modules as either:instead of calling
Object.entries()on whatever non-tool shape it ends up with. The 1.14.48 behavior of "silently tolerate barrels" is the user-friendly default; even rejecting them with a clear error message would be much better than the current genericUnexpected server error.Workaround for users
Until this is fixed, replace any re-exporting
tool/index.tswith:And import tools directly from their subdirectories (
./gemini,./template, etc.) instead of through the barrel.