

























@@ -75,6 +75,7 @@ type ConfigSetOperation = {
75757676const GATEWAY_AUTH_MODE_PATH: PathSegment[] = ["gateway", "auth", "mode"];
7777const SECRET_PROVIDER_PATH_PREFIX: PathSegment[] = ["secrets", "providers"];
78+const PLUGIN_INSTALL_RECORD_PATH_PREFIX: PathSegment[] = ["plugins", "installs"];
7879const CONFIG_SET_EXAMPLE_VALUE = formatCliCommand(
7980"openclaw config set gateway.port 19001 --strict-json",
8081);
@@ -1088,6 +1089,21 @@ function selectDryRunRefsForResolution(params: { refs: SecretRef[]; allowExecInD
10881089return { refsToResolve, skippedExecRefs };
10891090}
109010911092+function pathStartsWith(path: readonly PathSegment[], prefix: readonly PathSegment[]): boolean {
1093+return prefix.every((segment, index) => path[index] === segment);
1094+}
1095+1096+function formatPluginInstallConfigSetError(): string {
1097+return [
1098+"plugins.installs is managed by the plugin index and cannot be edited with config set.",
1099+"",
1100+"Use plugin commands instead:",
1101+` ${formatCliCommand("openclaw plugins install <spec>")}`,
1102+` ${formatCliCommand("openclaw plugins update <plugin-id>")}`,
1103+` ${formatCliCommand("openclaw plugins uninstall <plugin-id>")}`,
1104+].join("\n");
1105+}
1106+10911107function collectDryRunSchemaErrors(params: {
10921108config: OpenClawConfig;
10931109operations: ReadonlyArray<ConfigSetOperation>;
@@ -1192,6 +1208,13 @@ export async function runConfigSet(opts: {
11921208value: opts.value,
11931209opts: opts.cliOptions,
11941210});
1211+if (
1212+operations.some((operation) =>
1213+pathStartsWith(operation.requestedPath, PLUGIN_INSTALL_RECORD_PATH_PREFIX),
1214+)
1215+) {
1216+throw new Error(formatPluginInstallConfigSetError());
1217+}
11951218const snapshot = await loadValidConfig(runtime);
11961219// Use snapshot.resolved (config after $include and ${ENV} resolution, but BEFORE runtime defaults)
11971220// instead of snapshot.config (runtime-merged with defaults).
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。