Skip to content

Commit 346e327

Browse files
committed
fix(cli): guide onboarding option errors
1 parent 021565b commit 346e327

7 files changed

Lines changed: 32 additions & 8 deletions

File tree

src/cli/gateway-cli/run.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ async function runGatewayCommand(opts: GatewayRunOpts) {
477477
wsLogRaw !== "compact" &&
478478
wsLogRaw !== "full"
479479
) {
480-
defaultRuntime.error('Invalid --ws-log (use "auto", "full", "compact")');
480+
defaultRuntime.error('Invalid --ws-log. Use "auto", "full", or "compact".');
481481
defaultRuntime.exit(1);
482482
}
483483
setGatewayWsLogStyle(wsLogStyle);
@@ -560,7 +560,7 @@ async function runGatewayCommand(opts: GatewayRunOpts) {
560560
toOptionString(opts.bind) ?? cfg.gateway?.bind,
561561
);
562562
if (bindExplicitRawStr !== undefined && !VALID_BIND_MODES.has(bindExplicitRawStr)) {
563-
defaultRuntime.error('Invalid --bind (use "loopback", "lan", "tailnet", "auto", or "custom")');
563+
defaultRuntime.error('Invalid --bind. Use "loopback", "lan", "tailnet", "auto", or "custom".');
564564
defaultRuntime.exit(1);
565565
return;
566566
}

src/commands/configure.gateway-auth.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { ensureAuthProfileStore } from "../agents/auth-profiles.js";
22
import { resolveDefaultAgentWorkspaceDir } from "../agents/workspace.js";
3+
import { formatCliCommand } from "../cli/command-format.js";
34
import type { OpenClawConfig, GatewayAuthConfig } from "../config/config.js";
45
import { isSecretRef, type SecretInput } from "../config/types.secrets.js";
56
import type { RuntimeEnv } from "../runtime.js";
@@ -161,7 +162,9 @@ export function buildGatewayAuthConfig(params: {
161162
}
162163
if (params.mode === "trusted-proxy") {
163164
if (!params.trustedProxy) {
164-
throw new Error("trustedProxy config is required when mode is trusted-proxy");
165+
throw new Error(
166+
`trustedProxy config is required when mode is trusted-proxy. Run ${formatCliCommand("openclaw configure --section gateway")} to configure Gateway auth interactively.`,
167+
);
165168
}
166169
return { ...base, mode: "trusted-proxy", trustedProxy: params.trustedProxy };
167170
}

src/commands/models/aliases.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { formatCliCommand } from "../../cli/command-format.js";
12
import { logConfigUpdated } from "../../config/logging.js";
23
import { type RuntimeEnv, writeRuntimeJson } from "../../runtime.js";
34
import { loadModelsConfig } from "./load-config.js";
@@ -95,7 +96,9 @@ export async function modelsAliasesRemoveCommand(aliasRaw: string, runtime: Runt
9596
}
9697
}
9798
if (!found) {
98-
throw new Error(`Alias not found: ${alias}`);
99+
throw new Error(
100+
`Alias not found: ${alias}. Run ${formatCliCommand("openclaw models aliases list")} to see configured aliases.`,
101+
);
99102
}
100103
return {
101104
...cfg,

src/commands/models/fallbacks-shared.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { buildModelAliasIndex, resolveModelRefFromString } from "../../agents/model-selection.js";
2+
import { formatCliCommand } from "../../cli/command-format.js";
23
import { logConfigUpdated } from "../../config/logging.js";
34
import { resolveAgentModelFallbackValues, toAgentModelListLike } from "../../config/model-input.js";
45
import type { AgentModelEntryConfig } from "../../config/types.agent-defaults.js";
@@ -18,6 +19,12 @@ import {
1819

1920
type DefaultsFallbackKey = "model" | "imageModel";
2021

22+
function listCommandForFallbackKey(key: DefaultsFallbackKey): string {
23+
return key === "imageModel"
24+
? "openclaw models image-fallbacks list"
25+
: "openclaw models fallbacks list";
26+
}
27+
2128
function getFallbacks(cfg: OpenClawConfig, key: DefaultsFallbackKey): string[] {
2229
return resolveAgentModelFallbackValues(cfg.agents?.defaults?.[key]);
2330
}
@@ -133,7 +140,9 @@ export async function removeFallbackCommand(
133140
});
134141

135142
if (filtered.length === existing.length) {
136-
throw new Error(`${params.notFoundLabel} not found: ${targetKey}`);
143+
throw new Error(
144+
`${params.notFoundLabel} not found: ${targetKey}. Run ${formatCliCommand(listCommandForFallbackKey(params.key))} to see configured fallbacks.`,
145+
);
137146
}
138147

139148
return patchDefaultsFallbacks(cfg, { key: params.key, fallbacks: filtered });

src/commands/models/scan.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { cancel, multiselect as clackMultiselect, isCancel } from "@clack/prompt
22
import { getEnvApiKey } from "@mariozechner/pi-ai";
33
import { resolveApiKeyForProvider } from "../../agents/model-auth.js";
44
import { type ModelScanResult, scanOpenRouterModels } from "../../agents/model-scan.js";
5+
import { formatCliCommand } from "../../cli/command-format.js";
56
import { withProgressTotals } from "../../cli/progress.js";
67
import { logConfigUpdated } from "../../config/logging.js";
78
import { toAgentModelListLike } from "../../config/model-input.js";
@@ -266,7 +267,9 @@ export async function modelsScanCommand(
266267

267268
const toolOk = results.filter((entry) => entry.tool.ok);
268269
if (toolOk.length === 0) {
269-
throw new Error("No tool-capable OpenRouter free models found.");
270+
throw new Error(
271+
`No tool-capable OpenRouter free models found. Try ${formatCliCommand("openclaw models scan --no-probe")} to inspect metadata-only candidates, or configure OPENROUTER_API_KEY before probing.`,
272+
);
270273
}
271274

272275
const sorted = sortScanResults(results);

src/commands/onboard-non-interactive/api-keys.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
resolveAuthProfileOrder,
55
} from "../../agents/auth-profiles.js";
66
import { resolveEnvApiKey } from "../../agents/model-auth.js";
7+
import { formatCliCommand } from "../../cli/command-format.js";
78
import type { OpenClawConfig } from "../../config/types.openclaw.js";
89
import type { RuntimeEnv } from "../../runtime.js";
910
import { normalizeOptionalSecretInput } from "../../utils/normalize-secret-input.js";
@@ -134,7 +135,9 @@ export async function resolveNonInteractiveApiKey(params: {
134135

135136
const profileHint =
136137
params.allowProfile === false ? "" : `, or existing ${params.provider} API-key profile`;
137-
params.runtime.error(`Missing ${params.flagName} (or ${params.envVar} in env${profileHint}).`);
138+
params.runtime.error(
139+
`Missing ${params.flagName} (or ${params.envVar} in env${profileHint}). Export ${params.envVar}, pass ${params.flagName}, or run ${formatCliCommand("openclaw onboard")} for interactive setup.`,
140+
);
138141
params.runtime.exit(1);
139142
return null;
140143
}

src/commands/onboard-non-interactive/local/auth-choice.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { ApiKeyCredential } from "../../../agents/auth-profiles/types.js";
2+
import { formatCliCommand } from "../../../cli/command-format.js";
23
import type { OpenClawConfig } from "../../../config/types.openclaw.js";
34
import type { SecretInput } from "../../../config/types.secrets.js";
45
import { formatErrorMessage } from "../../../infra/errors.js";
@@ -42,7 +43,9 @@ export async function applyNonInteractiveAuthChoice(params: {
4243
let nextConfig = params.nextConfig;
4344
const requestedSecretInputMode = normalizeSecretInputModeInput(opts.secretInputMode);
4445
if (opts.secretInputMode && !requestedSecretInputMode) {
45-
runtime.error('Invalid --secret-input-mode. Use "plaintext" or "ref".');
46+
runtime.error(
47+
`Invalid --secret-input-mode. Use "plaintext" or "ref", or run ${formatCliCommand("openclaw onboard")} for interactive setup.`,
48+
);
4649
runtime.exit(1);
4750
return null;
4851
}

0 commit comments

Comments
 (0)