@@ -1220,49 +1220,66 @@ describe("config io write", () => {
12201220 } ) ;
12211221
12221222 it ( "skipPluginValidation bypasses plugin schema rejection on writeConfigFile (#76800)" , async ( ) => {
1223- mockLoadPluginManifestRegistry . mockReturnValue ( {
1224- diagnostics : [ ] ,
1225- plugins : [
1226- {
1227- id : "strict-plugin" ,
1228- origin : "bundled" ,
1229- channels : [ ] ,
1230- providers : [ ] ,
1231- cliBackends : [ ] ,
1232- skills : [ ] ,
1233- hooks : [ ] ,
1234- rootDir : "/tmp/openclaw-test-strict-plugin" ,
1235- source : "/tmp/openclaw-test-strict-plugin/index.ts" ,
1236- manifestPath : "/tmp/openclaw-test-strict-plugin/openclaw.plugin.json" ,
1237- configSchema : {
1238- type : "object" ,
1239- properties : { token : { type : "string" } } ,
1240- required : [ "token" ] ,
1241- additionalProperties : false ,
1242- } ,
1243- } ,
1244- ] ,
1245- } satisfies PluginManifestRegistry ) ;
1246-
12471223 await withSuiteHome ( async ( home ) => {
12481224 const configPath = path . join ( home , ".openclaw" , "openclaw.json" ) ;
1225+ const previousConfigPath = process . env . OPENCLAW_CONFIG_PATH ;
1226+ process . env . OPENCLAW_CONFIG_PATH = configPath ;
12491227 await fs . mkdir ( path . dirname ( configPath ) , { recursive : true } ) ;
12501228 await fs . writeFile ( configPath , "{}\n" , "utf-8" ) ;
1251- // Plugin is enabled but missing required "token" — validation fails without skip
1252- const cfg : OpenClawConfig = {
1253- agents : { list : [ { id : "main" , default : true } ] } ,
1254- plugins : { entries : { "strict-plugin" : { enabled : true } } } ,
1255- } ;
1229+ mockLoadPluginManifestRegistry . mockReturnValue ( {
1230+ diagnostics : [ ] ,
1231+ plugins : [
1232+ {
1233+ id : "strict-plugin" ,
1234+ origin : "bundled" ,
1235+ channels : [ ] ,
1236+ providers : [ ] ,
1237+ cliBackends : [ ] ,
1238+ skills : [ ] ,
1239+ hooks : [ ] ,
1240+ rootDir : "/tmp/openclaw-test-strict-plugin" ,
1241+ source : "/tmp/openclaw-test-strict-plugin/index.ts" ,
1242+ manifestPath : "/tmp/openclaw-test-strict-plugin/openclaw.plugin.json" ,
1243+ configSchema : {
1244+ type : "object" ,
1245+ properties : { token : { type : "string" } } ,
1246+ required : [ "token" ] ,
1247+ additionalProperties : false ,
1248+ } ,
1249+ } ,
1250+ ] ,
1251+ } satisfies PluginManifestRegistry ) ;
12561252
1257- await expect ( writeConfigFile ( cfg , { skipPluginValidation : true } ) ) . resolves . not . toThrow ( ) ;
1253+ try {
1254+ // Plugin is enabled but missing required "token" — validation fails without skip.
1255+ const cfg : OpenClawConfig = {
1256+ agents : { list : [ { id : "main" , default : true } ] } ,
1257+ plugins : { entries : { "strict-plugin" : { enabled : true } } } ,
1258+ } ;
12581259
1259- await expect ( writeConfigFile ( cfg , { skipPluginValidation : false } ) ) . rejects . toThrow ( ) ;
1260- } ) ;
1260+ await expect ( writeConfigFile ( cfg , { skipPluginValidation : true } ) ) . resolves . not . toThrow ( ) ;
1261+ await expect ( fs . readFile ( configPath , "utf-8" ) ) . resolves . toContain ( '"strict-plugin"' ) ;
12611262
1262- mockLoadPluginManifestRegistry . mockReturnValue ( {
1263- diagnostics : [ ] ,
1264- plugins : [ ] ,
1265- } satisfies PluginManifestRegistry ) ;
1263+ await expect ( writeConfigFile ( cfg , { skipPluginValidation : false } ) ) . rejects . toThrow (
1264+ / C o n f i g v a l i d a t i o n f a i l e d / ,
1265+ ) ;
1266+ await expect (
1267+ writeConfigFile ( { agents : { list : "not-array" } } as unknown as OpenClawConfig , {
1268+ skipPluginValidation : true ,
1269+ } ) ,
1270+ ) . rejects . toThrow ( / C o n f i g v a l i d a t i o n f a i l e d / ) ;
1271+ } finally {
1272+ mockLoadPluginManifestRegistry . mockReturnValue ( {
1273+ diagnostics : [ ] ,
1274+ plugins : [ ] ,
1275+ } satisfies PluginManifestRegistry ) ;
1276+ if ( previousConfigPath === undefined ) {
1277+ delete process . env . OPENCLAW_CONFIG_PATH ;
1278+ } else {
1279+ process . env . OPENCLAW_CONFIG_PATH = previousConfigPath ;
1280+ }
1281+ }
1282+ } ) ;
12661283 } ) ;
12671284
12681285 it ( "preserves authored tilde paths when runtime-shaped writes hand back absolute paths" , async ( ) => {
0 commit comments