mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-21 10:16:44 +00:00
fix(doctor): preserve plugin validation during migration
This commit is contained in:
@@ -52,7 +52,7 @@ Rapid consecutive text messages from the same sender can be batched into one age
|
||||
- Debounce applies to text-only messages; media/attachments flush immediately.
|
||||
- Control commands (stop/abort/status, etc.) bypass debouncing so they dispatch immediately.
|
||||
- Disabled by default: `messages.inbound.debounceMs` has no built-in default, so debouncing only activates once you set it (globally or per channel).
|
||||
- iMessage follows the same generic inbound debounce policy when `messages.inbound` is configured. Apple URL-preview split-sends are coalesced by `imsg >= 0.11.1` before OpenClaw receives them, so they do not need an OpenClaw debounce exception.
|
||||
- iMessage follows the same generic inbound debounce policy when `messages.inbound` is configured. Apple URL-preview split-sends are coalesced by `imsg >= 0.13.1` before OpenClaw receives them, so they do not need an OpenClaw debounce exception.
|
||||
|
||||
## Sessions and devices
|
||||
|
||||
|
||||
@@ -273,4 +273,43 @@ describe("runDoctorConfigPreflight", () => {
|
||||
await expect(fs.readFile(configPath, "utf-8")).resolves.toBe(lastGoodRaw);
|
||||
});
|
||||
});
|
||||
|
||||
it("does not let a legacy channel key hide unrelated malformed plugin config", async () => {
|
||||
await withTempHome(async (home) => {
|
||||
const configPath = await writeOpenClawConfig(home, {
|
||||
gateway: { mode: "local", port: 19091 },
|
||||
});
|
||||
await promoteConfigSnapshotToLastKnownGood(await readConfigFileSnapshot());
|
||||
const lastGoodRaw = await fs.readFile(configPath, "utf-8");
|
||||
await fs.writeFile(
|
||||
configPath,
|
||||
`${JSON.stringify(
|
||||
{
|
||||
gateway: { mode: "local", port: 19092 },
|
||||
channels: {
|
||||
imessage: {
|
||||
enabled: true,
|
||||
coalesceSameSenderDms: true,
|
||||
mediaMaxMb: "bad",
|
||||
},
|
||||
},
|
||||
},
|
||||
null,
|
||||
2,
|
||||
)}\n`,
|
||||
"utf-8",
|
||||
);
|
||||
|
||||
const repaired = await runDoctorConfigPreflight({
|
||||
migrateState: false,
|
||||
migrateLegacyConfig: false,
|
||||
repairPrefixedConfig: true,
|
||||
invalidConfigNote: false,
|
||||
});
|
||||
|
||||
expect(repaired.snapshot.valid).toBe(true);
|
||||
expect(repaired.snapshot.config.gateway?.port).toBe(19091);
|
||||
await expect(fs.readFile(configPath, "utf-8")).resolves.toBe(lastGoodRaw);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,12 +13,14 @@ import {
|
||||
import { formatConfigIssueLines } from "../config/issue-format.js";
|
||||
import type { ConfigFileSnapshot, LegacyConfigIssue } from "../config/types.js";
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
import { validateConfigObjectWithPlugins } from "../config/validation.js";
|
||||
import { isTruthyEnvValue } from "../infra/env.js";
|
||||
import type { StartupMigrationLease } from "../infra/startup-migration-checkpoint.js";
|
||||
import { createLazyRuntimeModule } from "../shared/lazy-runtime.js";
|
||||
import { resolveHomeDir } from "../utils.js";
|
||||
import { noteIncludeConfinementWarning } from "./doctor-config-analysis.js";
|
||||
import type { CronCodexRuntimePolicyTarget } from "./doctor/cron/store-migration.js";
|
||||
import { normalizeCompatibilityConfigValues } from "./doctor/shared/legacy-config-core-migrate.js";
|
||||
import { findDoctorLegacyConfigIssues } from "./doctor/shared/legacy-config-issues.js";
|
||||
import { resolveStateMigrationConfigInput } from "./doctor/shared/legacy-config-state-migration-input.js";
|
||||
|
||||
@@ -335,11 +337,20 @@ export async function runDoctorConfigPreflight(
|
||||
!next.valid &&
|
||||
next.legacyIssues.length > 0
|
||||
) {
|
||||
next = addDoctorLegacyIssues(
|
||||
const legacySnapshot = addDoctorLegacyIssues(
|
||||
await measureStartupPreflightStep("config-snapshot-legacy-plugin", () =>
|
||||
readConfigFileSnapshot({ ...readOptions, skipPluginValidation: true }),
|
||||
),
|
||||
);
|
||||
if (legacySnapshot.valid) {
|
||||
// Only bypass the stale schema long enough to prove that applying the
|
||||
// registered doctor migrations leaves no unrelated plugin errors.
|
||||
const rawConfig = legacySnapshot.sourceConfig ?? legacySnapshot.config ?? {};
|
||||
const normalized = normalizeCompatibilityConfigValues(rawConfig);
|
||||
if (validateConfigObjectWithPlugins(normalized.config).ok) {
|
||||
next = legacySnapshot;
|
||||
}
|
||||
}
|
||||
}
|
||||
return next;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user