mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-25 03:45:46 -06:00
fix(onboard): stop a full reset from resetting the default workspace when the config is unreadable (#114110)
The unreadable-config guard tested !snapshot.sourceConfig, but
ConfigFileSnapshot.sourceConfig is required and every construction site
passes an object ({} when the read failed), so the guard never fired and
--reset-scope full fell through to its DEFAULT_WORKSPACE fallback.
Test it against snapshot.readError, the field io.snapshot.ts sets only when
the config file could not be read. A readable config that simply configures
no workspace keeps using the default.
Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import { formatCliCommand } from "../cli/command-format.js";
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
import type { ProviderAuthMethod, ProviderPlugin } from "../plugins/types.js";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
import { resolveUserPath } from "../utils.js";
|
||||
import { setupWizardCommand } from "./onboard.js";
|
||||
|
||||
type ConfigSnapshotStub = {
|
||||
@@ -12,6 +13,7 @@ type ConfigSnapshotStub = {
|
||||
valid: boolean;
|
||||
config: OpenClawConfig;
|
||||
sourceConfig?: OpenClawConfig;
|
||||
readError?: { code: string | null };
|
||||
};
|
||||
|
||||
type ProviderAuthMethodNonInteractiveValidationContext = Parameters<
|
||||
@@ -364,10 +366,14 @@ describe("setupWizardCommand", () => {
|
||||
|
||||
it("requires an explicit workspace for a full reset when config is unreadable", async () => {
|
||||
const runtime = makeRuntime();
|
||||
// readConfigFileSnapshot always returns a sourceConfig object, so an
|
||||
// unreadable config is only recognizable through readError.
|
||||
mocks.readConfigFileSnapshot.mockResolvedValue({
|
||||
exists: true,
|
||||
valid: false,
|
||||
config: {},
|
||||
sourceConfig: {},
|
||||
readError: { code: "EACCES" },
|
||||
});
|
||||
|
||||
await setupWizardCommand(
|
||||
@@ -384,6 +390,30 @@ describe("setupWizardCommand", () => {
|
||||
expect(mocks.handleReset).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("uses the default workspace for a full reset when a readable config configures none", async () => {
|
||||
const runtime = makeRuntime();
|
||||
mocks.readConfigFileSnapshot.mockResolvedValue({
|
||||
exists: true,
|
||||
valid: false,
|
||||
config: {},
|
||||
sourceConfig: { gateway: { port: 1 } },
|
||||
});
|
||||
|
||||
await setupWizardCommand(
|
||||
{
|
||||
reset: true,
|
||||
resetScope: "full",
|
||||
},
|
||||
runtime,
|
||||
);
|
||||
|
||||
expect(mocks.handleReset).toHaveBeenCalledWith(
|
||||
"full",
|
||||
resolveUserPath("~/.openclaw/workspace"),
|
||||
runtime,
|
||||
);
|
||||
});
|
||||
|
||||
it("accepts explicit --reset-scope full", async () => {
|
||||
const runtime = makeRuntime();
|
||||
|
||||
|
||||
@@ -578,7 +578,10 @@ export async function setupWizardCommand(
|
||||
normalizedOpts.workspace === undefined &&
|
||||
snapshot.exists &&
|
||||
!snapshot.valid &&
|
||||
!snapshot.sourceConfig
|
||||
// A snapshot always carries a sourceConfig object (empty on failure), so
|
||||
// only readError distinguishes "config could not be read" from "config
|
||||
// parsed but configures no workspace", where the default is correct.
|
||||
snapshot.readError !== undefined
|
||||
) {
|
||||
rejectOption(
|
||||
runtime,
|
||||
|
||||
Reference in New Issue
Block a user