Skip to content

[Bug] pi agent catalog fails: 'model must be provider/modelId' when account default model is a bare id; SDK missing (ERR_MODULE_NOT_FOUND) until managed runtime ready #438

Description

@baoyu0

Summary

The pi agent catalog fails to load when the active account's default model is a bare model id (e.g. deepseek-v4-flash), because the pi adapter requires provider/modelId format and throws, which fails the whole catalog. Separately, at startup the daemon reports @earendil-works/pi-coding-agent as missing (ERR_MODULE_NOT_FOUND) until the managed runtime asset is ready, producing repeated "Failed to load agent catalog" noise.

Environment

  • LinkCode desktop 0.20.0
  • Windows 11 x64
  • Account created from the "opencode-go" service catalog: { "model": "deepseek-v4-flash", "endpoint": { "baseUrl": "https://opencode.ai/zen/go/v1", "protocol": "openai-chat" } }

Symptom

%APPDATA%\LinkCode\logs\main.log:

{"subsystem":"agent","operation":"agent.catalog","err":{"type":"Error",
 "message":"pi: model must be 'provider/modelId' (got 'deepseek-v4-flash')",
 "stack":"Error: pi: model must be 'provider/modelId' (got 'deepseek-v4-flash')
   at createConfiguredRegistry (.../out/daemon/index.mjs:97941:11)
   at PiAdapter.startCatalog (.../out/daemon/index.mjs:97993:17)"},
 "msg":"Failed to load agent catalog"}

and, during the first ~20 s after startup:

"message":"pi: SDK '@earendil-works/pi-coding-agent' is unavailable (Error: Cannot find package '@earendil-works/pi-coding-agent' imported from .../out/daemon/index.mjs)"
"cause":{"code":"ERR_MODULE_NOT_FOUND"}

Root cause 1 — model format

PiAdapter.startCatalogcreateConfiguredRegistry does:

const ref = opts.model ? parseModel(opts.model) : null;
if (!ref && opts.model) {
  throw new Error(`pi: model must be 'provider/modelId' (got '${opts.model}')`);
}

opts.model is the account's default model, which service-catalog accounts store as a bare id (the correct format for the claude-code/codex/opencode CLIs that share the same account). A bare id makes pi's catalog throw, so the pi agent surface is entirely unavailable until the user manually sets the model to provider/modelId (e.g. opencode-go/deepseek-v4-flash).

Root cause 2 — SDK not bundled

PiAdapter.importSdk() first tries agentRuntimeProber.resolveEntry("pi") (the managed runtime asset) and only falls back to import("@earendil-works/pi-coding-agent"), which is not bundled in app.asar. Catalog retries fail with ERR_MODULE_NOT_FOUND until asset.ensure finishes ("Managed agent runtime ready", ~20 s after startup). If the managed runtime is GC'd by asset.gc (we observed "Removed superseded managed assets"), the errors return until the asset is re-ensured.

Repro

  1. Create an account from a service catalog with a bare default model (e.g. deepseek-v4-flash).
  2. Enable the pi provider.
  3. Restart the app; watch agent.catalog errors in main.log.

Workaround

Set the account's model to provider/modelId format (e.g. opencode-go/deepseek-v4-flash) in the app settings or ~/.linkcode/config.json.

Suggested fix

  • pi adapter: tolerate bare model ids by defaulting the provider to the account's service/endpoint name instead of throwing (or normalize the account model when configuring pi), so a shared account with a bare model id still produces a working catalog.
  • Packaging: bundle @earendil-works/pi-coding-agent in the app, or gate catalog errors on the managed-runtime readiness state to avoid the misleading ERR_MODULE_NOT_FOUND noise.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions