diff --git a/src/commands/onboard-non-interactive.provider-auth.test.ts b/src/commands/onboard-non-interactive.provider-auth.test.ts index 390d19b0154..d72de28a61d 100644 --- a/src/commands/onboard-non-interactive.provider-auth.test.ts +++ b/src/commands/onboard-non-interactive.provider-auth.test.ts @@ -42,6 +42,11 @@ let upsertAuthProfile: typeof import("../agents/auth-profiles.js").upsertAuthPro type ProviderAuthConfigSnapshot = { auth?: { profiles?: Record }; agents?: { defaults?: { model?: { primary?: string } } }; + talk?: { + provider?: string; + apiKey?: string | { source?: string; id?: string }; + providers?: Record; + }; models?: { providers?: Record< string, @@ -357,6 +362,38 @@ describe("onboard (non-interactive): provider auth", () => { }); }); + it("does not persist talk fallback secrets when OpenAI ref onboarding starts from an empty config", async () => { + await withOnboardEnv("openclaw-onboard-openai-ref-no-talk-leak-", async (env) => { + await withEnvAsync( + { + OPENAI_API_KEY: "sk-openai-env-key", // pragma: allowlist secret + ELEVENLABS_API_KEY: "elevenlabs-env-key", // pragma: allowlist secret + }, + async () => { + const cfg = await runOnboardingAndReadConfig(env, { + authChoice: "openai-api-key", + secretInputMode: "ref", // pragma: allowlist secret + }); + + expect(cfg.agents?.defaults?.model?.primary).toBe(OPENAI_DEFAULT_MODEL); + expect(cfg.talk).toBeUndefined(); + + const store = ensureAuthProfileStore(); + const profile = store.profiles["openai:default"]; + expect(profile?.type).toBe("api_key"); + if (profile?.type === "api_key") { + expect(profile.key).toBeUndefined(); + expect(profile.keyRef).toEqual({ + source: "env", + provider: "default", + id: "OPENAI_API_KEY", + }); + } + }, + ); + }); + }); + it.each([ { name: "anthropic", diff --git a/src/commands/onboard-non-interactive.ts b/src/commands/onboard-non-interactive.ts index 4b4d1223226..ee2b3498180 100644 --- a/src/commands/onboard-non-interactive.ts +++ b/src/commands/onboard-non-interactive.ts @@ -20,7 +20,7 @@ export async function runNonInteractiveOnboarding( return; } - const baseConfig: OpenClawConfig = snapshot.valid ? snapshot.config : {}; + const baseConfig: OpenClawConfig = snapshot.valid ? (snapshot.exists ? snapshot.config : {}) : {}; const mode = opts.mode ?? "local"; if (mode !== "local" && mode !== "remote") { runtime.error(`Invalid --mode "${String(mode)}" (use local|remote).`); diff --git a/src/wizard/onboarding.ts b/src/wizard/onboarding.ts index e2a81537eb7..47825eeae52 100644 --- a/src/wizard/onboarding.ts +++ b/src/wizard/onboarding.ts @@ -81,7 +81,7 @@ export async function runOnboardingWizard( await requireRiskAcknowledgement({ opts, prompter }); const snapshot = await readConfigFileSnapshot(); - let baseConfig: OpenClawConfig = snapshot.valid ? snapshot.config : {}; + let baseConfig: OpenClawConfig = snapshot.valid ? (snapshot.exists ? snapshot.config : {}) : {}; if (snapshot.exists && !snapshot.valid) { await prompter.note(onboardHelpers.summarizeExistingConfig(baseConfig), "Invalid config");