paperclipai/paperclip · warning

[opencode-local] Remote `opencode models` returned no models

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.

Source

Thrown at packages/adapters/opencode-local/src/server/execute.ts:151

    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 ? ", ..." : ""}`,
    );
  }
}

function claudeSkillsHome(): string {
  return path.join(os.homedir(), ".claude", "skills");
}

async function ensureOpenCodeSkillsInjected(

View on GitHub (pinned to 120ae5428f)

Solutions

  1. SSH to the remote host and run `opencode models` manually; confirm it lists the configured model id.
  2. Authenticate the provider on the remote (`opencode auth login`) or forward the provider API key via the adapter's env configuration.
  3. Verify the model id in the Paperclip agent/model config exactly matches a listed id (case-sensitive).
  4. 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

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


AI-assisted analysis of paperclipai/paperclip@120ae5428f (2026-08-18). Data as JSON: /api/errors/fed647a5a3be7160. Report an issue: GitHub.