Skip to content

Commit 21d919d

Browse files
authored
fix(onboard): keep the wizard alive through provider auth failures and polish standalone install UX (#100632)
Fixes rough edges in the standalone install flow (install.sh -> openclaw onboard), found and verified by running the flow in a clean container and on a clean macOS Tahoe VM: - Provider auth setup failures (e.g. the preselected "Anthropic Claude CLI" option on a host without a Claude CLI login) no longer kill the whole wizard. The interactive wizard notes the error and returns to the provider picker; explicit --auth-choice automation still fails fast. - Onboarding config now persists before the channel/search/skills steps, so a crash or cancel during channel pairing no longer loses auth + gateway decisions. - With model auth skipped, finalize no longer auto-sends the "Wake up, my friend!" message (which always failed with a provider auth error). The hatch seed is gated on usable model credentials and a "Model auth missing" note explains the next step. - Search provider picker no longer labels non-key credentials (e.g. SearXNG base URL) as "API key required". - install.sh no longer warns "PATH missing npm global bin dir" with manual fix steps after it already persisted the export line; it reports the PATH was updated and how to reload the current shell. - Removed the dead interactive hooks onboarding step (setupInternalHooks); quickstart enables default hooks silently. Verified live per fix in a clean Debian/Node 24 container and on a clean macOS 26.5 Parallels VM (wizard re-prompt, SearXNG label), plus wizard/onboard test suites and tsgo:core. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
1 parent 95f4674 commit 21d919d

18 files changed

Lines changed: 310 additions & 414 deletions

docs/help/faq-first-run.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,10 @@ and troubleshooting see the main [FAQ](/help/faq).
181181

182182
<Accordion title="It is stuck on wake up my friend / onboarding will not hatch. What now?">
183183
That screen depends on the Gateway being reachable and authenticated. The TUI also sends
184-
"Wake up, my friend!" automatically on first hatch. If you see that line with **no reply**
185-
and tokens stay at 0, the agent never ran.
184+
"Wake up, my friend!" automatically on first hatch when a model provider is configured. If
185+
you skipped model/auth setup, onboarding shows a "Model auth missing" note and opens the
186+
TUI without sending anything — add a provider with `openclaw configure --section model`.
187+
If you see the wake-up line with **no reply** and tokens stay at 0, the agent never ran.
186188

187189
1. Restart the Gateway:
188190

docs/start/wizard-cli-reference.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,10 @@ Plaintext `ws://` is accepted for loopback, private IP literals, `.local`, and T
157157

158158
## Auth and model options
159159

160+
If a provider setup step fails in interactive onboarding (for example a CLI reuse option
161+
without a local sign-in), the wizard shows the error and returns to the provider picker
162+
instead of exiting. Explicit `--auth-choice` runs still fail fast for automation.
163+
160164
<AccordionGroup>
161165
<Accordion title="Anthropic API key">
162166
Uses `ANTHROPIC_API_KEY` if present or prompts for a key, then saves it for daemon use.

scripts/install.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2487,6 +2487,20 @@ warn_shell_path_missing_dir() {
24872487
return 0
24882488
fi
24892489

2490+
# persist_shell_path_prepend may already have written the export line; in
2491+
# that case new shells are fine and the user only needs to reload this one.
2492+
# RC lines may spell the home dir as $HOME instead of the expanded path.
2493+
local dir_home_form="\$HOME${dir#"$HOME"}"
2494+
for rc in "$HOME/.bashrc" "$HOME/.zshrc"; do
2495+
if [[ -f "$rc" ]] && { grep -Fq "$dir" "$rc" || grep -Fq "$dir_home_form" "$rc"; }; then
2496+
echo ""
2497+
ui_info "PATH updated in ${rc}: added ${label} (${dir})"
2498+
echo " New terminals pick this up automatically."
2499+
echo " For this shell, run: source ${rc}"
2500+
return 0
2501+
fi
2502+
done
2503+
24902504
echo ""
24912505
ui_warn "PATH missing ${label}: ${dir}"
24922506
echo " This can make openclaw show as \"command not found\" in new terminals."

src/commands/auth-choice.model-check.ts

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,37 @@ function hasProfileForProvider(params: {
6868
});
6969
}
7070

71+
/**
72+
* Resolve the default model ref and whether any usable credentials exist for
73+
* it (auth profiles, provider env keys, or custom provider API keys). Shared
74+
* by the onboarding model check and the finalize hatch gating.
75+
*/
76+
export function resolveDefaultModelAuthStatus(
77+
config: OpenClawConfig,
78+
options?: { agentId?: string; agentDir?: string },
79+
): { provider: string; model: string; hasAuth: boolean } {
80+
const ref = resolveDefaultModelForAgent({
81+
cfg: config,
82+
agentId: options?.agentId,
83+
});
84+
const store = ensureAuthProfileStore(options?.agentDir);
85+
const authProviders = resolveAuthProviderCandidates({
86+
config,
87+
provider: ref.provider,
88+
modelId: ref.model,
89+
agentId: options?.agentId,
90+
});
91+
const acceptedTypes = resolveAcceptedAuthProfileTypes({
92+
config,
93+
provider: ref.provider,
94+
});
95+
const hasAuth =
96+
authProviders.some((provider) => hasProfileForProvider({ store, provider, acceptedTypes })) ||
97+
authProviders.some((provider) => resolveEnvApiKey(provider)) ||
98+
authProviders.some((provider) => hasUsableCustomProviderApiKey(config, provider));
99+
return { provider: ref.provider, model: ref.model, hasAuth };
100+
}
101+
71102
/** Warn when the selected default model is unknown or has no usable credentials. */
72103
export async function warnIfModelConfigLooksOff(
73104
config: OpenClawConfig,
@@ -96,21 +127,10 @@ export async function warnIfModelConfigLooksOff(
96127
}
97128
}
98129

99-
const store = ensureAuthProfileStore(options?.agentDir);
100-
const authProviders = resolveAuthProviderCandidates({
101-
config,
102-
provider: ref.provider,
103-
modelId: ref.model,
104-
agentId: options?.agentId,
105-
});
106-
const acceptedTypes = resolveAcceptedAuthProfileTypes({
107-
config,
108-
provider: ref.provider,
130+
const { hasAuth } = resolveDefaultModelAuthStatus(config, {
131+
...(options?.agentId ? { agentId: options.agentId } : {}),
132+
...(options?.agentDir ? { agentDir: options.agentDir } : {}),
109133
});
110-
const hasAuth =
111-
authProviders.some((provider) => hasProfileForProvider({ store, provider, acceptedTypes })) ||
112-
authProviders.some((provider) => resolveEnvApiKey(provider)) ||
113-
authProviders.some((provider) => hasUsableCustomProviderApiKey(config, provider));
114134
if (!hasAuth) {
115135
warnings.push(
116136
`No auth configured for provider "${ref.provider}". The agent may fail until credentials are added. ${buildProviderAuthRecoveryHint(

src/commands/auth-choice.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
// Public auth-choice barrel used by onboarding and agent setup commands.
22
export { applyAuthChoice } from "./auth-choice.apply.js";
3-
export { warnIfModelConfigLooksOff } from "./auth-choice.model-check.js";
3+
export {
4+
resolveDefaultModelAuthStatus,
5+
warnIfModelConfigLooksOff,
6+
} from "./auth-choice.model-check.js";
47
export { resolvePreferredProviderForAuthChoice } from "../plugins/provider-auth-choice-preference.js";

0 commit comments

Comments
 (0)