Skip to content

Commit d8a3d9b

Browse files
committed
fix(onboard): keep the wizard alive through provider auth failures and polish standalone install UX
Rough edges found by running the standalone install flow (install.sh -> openclaw onboard) in a clean Debian/Node 24 container: - Provider auth setup failures (e.g. the preselected "Anthropic Claude CLI" option on a host without a Claude CLI login) killed the whole wizard and lost all progress. The interactive wizard now notes the error and returns to the provider picker; explicit --auth-choice automation still fails fast. - Onboarding config was only written after the channels step, so a crash or cancel during channel pairing lost auth + gateway decisions. The wizard now persists config before the channel/search/skills steps. - With model auth skipped, finalize auto-launched the TUI and auto-sent "Wake up, my friend!", which always failed with a confusing provider auth error. The seed message is now gated on usable model credentials and a "Model auth missing" note explains the next step (new resolveDefaultModelAuthStatus helper shared with the model check). - Search provider picker suffix said "API key required" even for non-key credentials (SearXNG base URL); it now uses the provider's credentialLabel. - install.sh warned "PATH missing npm global bin dir" with manual fix instructions even though it had already persisted the export line to the shell rc; it now says the PATH was updated and how to reload the current shell. - Delete the dead interactive hooks onboarding step (setupInternalHooks) left behind by the onboarding streamline; quickstart enables default hooks silently. Verified live in a clean container per fix (wizard re-prompt, no-auth hatch note, installer PATH message) plus wizard/onboard test suites.
1 parent 07bf384 commit d8a3d9b

18 files changed

Lines changed: 310 additions & 413 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
@@ -2466,6 +2466,20 @@ warn_shell_path_missing_dir() {
24662466
return 0
24672467
fi
24682468

2469+
# persist_shell_path_prepend may already have written the export line; in
2470+
# that case new shells are fine and the user only needs to reload this one.
2471+
# RC lines may spell the home dir as $HOME instead of the expanded path.
2472+
local dir_home_form="\$HOME${dir#"$HOME"}"
2473+
for rc in "$HOME/.bashrc" "$HOME/.zshrc"; do
2474+
if [[ -f "$rc" ]] && { grep -Fq "$dir" "$rc" || grep -Fq "$dir_home_form" "$rc"; }; then
2475+
echo ""
2476+
ui_info "PATH updated in ${rc}: added ${label} (${dir})"
2477+
echo " New terminals pick this up automatically."
2478+
echo " For this shell, run: source ${rc}"
2479+
return 0
2480+
fi
2481+
done
2482+
24692483
echo ""
24702484
ui_warn "PATH missing ${label}: ${dir}"
24712485
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)