paperclipai/paperclip · warning
[opencode-local] Remote `opencode models` returned no…
Error message
[opencode-local] Remote `opencode models` returned no models; proceeding with the configured model "${model}". What it means
The opencode-local adapter runs `opencode models` on the remote execution target as a best-effort pre-flight check that the configured model exists. When that command exits 0 but the parsed model list is empty, the adapter logs this warning and proceeds with the configured model anyway; the real invocation is authoritative. It is warn-only and never blocks the run by itself.
Solutions
- SSH to the remote host and run `opencode models` manually; confirm it lists the configured model id.
- Authenticate the provider on the remote (`opencode auth login`) or forward the provider API key via the adapter's env configuration.
- Verify the model id in the Paperclip agent/model config exactly matches a listed id (case-sensitive).
- Pin or upgrade the remote opencode CLI to a version whose `models` output the adapter parses.
Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight, on the remote host, before scheduling a run:
import { execFile } from 'node:child_process';
import { promisify } from 'node:util';
const exec = promisify(execFile);
async function remoteModelAvailable(model: string): Promise<boolean> {
const { stdout } = await exec('opencode', ['models']);
const ids = stdout.split('\n').map((l) => l.trim()).filter(Boolean);
return ids.includes(model);
}
// Skip or fix the run target when remoteModelAvailable(model) === false. Prevention
- Authenticate providers on every remote execution host, not just locally.
- Forward provider API-key env vars through the adapter's env configuration.
- Pin the opencode CLI version across hosts so `models` output stays parseable.
- Alert on this warn in server logs — it reliably predicts a later model-unavailable failure.
When it happens
Trigger: A run is dispatched to a remote target where `opencode models` succeeds but yields zero parsed entries: no provider authenticated on the remote host, an empty provider list in the remote opencode config, a transient provider-auth blip, or an `opencode` CLI version whose `models` output format the parser no longer recognizes.
Common situations: Fresh remote host with opencode installed but `opencode auth login` never run; provider API-key env vars not forwarded through the adapter's env config; remote opencode upgraded and its output shape changed; remote opencode.json pointing at a disabled provider.
Related errors
- [opencode-local] `opencode models` returned no models…
- A different semantic result was already committed
- ACPX Claude requires Linux x64 or macOS ARM64/x64.
- Could not verify the remote ACPX runner platform.
- Invalid semantic result
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-08-18).
Data as JSON: /api/errors/fed647a5a3be7160.
Report an issue: GitHub.
Appendix: source
Thrown at packages/adapters/opencode-local/src/server/execute.ts:153
// If `opencode models` itself cannot run on the target — timeout, transient CLI
// error, provider hiccup — do NOT abort the run. The real invocation is
// authoritative, so a probe that can't execute must never be fatal. (Previously
// these threw and crashed runs mid-flight, losing the agent's work + disposition.)
if (probe.timedOut) {
console.warn(
`[opencode-local] Remote model availability probe for "${model}" timed out after ${probeTimeoutSec}s; proceeding with the configured model.`,
);
return;
}
if ((probe.exitCode ?? 1) !== 0) {
const detail = firstNonEmptyLine(probe.stderr) || firstNonEmptyLine(probe.stdout);
console.warn(
`[opencode-local] Remote \`opencode models\` could not run for "${model}"${
detail ? ` (${detail})` : ""
}; proceeding with the configured model.`,
);
return;
}
const models = parseOpenCodeModelsOutput(probe.stdout);
if (models.length === 0) {
console.warn(
`[opencode-local] Remote \`opencode models\` returned no models; proceeding with the configured model "${model}".`,
);
return;
}
if (!models.some((entry) => entry.id === model)) {
const sample = models.slice(0, 12).map((entry) => entry.id).join(", ");
throw new Error(
`Configured OpenCode model is unavailable on the remote execution target: ${model}. Available models: ${sample}${models.length > 12 ? ", ..." : ""}`,
);
}
}
View on GitHub (pinned to 3f1d897a7c)