@@ -2775,7 +2775,10 @@ describe("doctor health contributions", () => {
27752775 ) . resolves . toMatchObject ( {
27762776 findings : [ ] ,
27772777 } ) ;
2778- expect ( accessSpy ) . toHaveBeenCalledWith ( "/tmp/openclaw-home" , fs . constants . W_OK ) ;
2778+ expect ( accessSpy ) . toHaveBeenCalledWith (
2779+ "/tmp/openclaw-home" ,
2780+ fs . constants . W_OK | fs . constants . X_OK ,
2781+ ) ;
27792782 } ) ;
27802783
27812784 it ( "reports an unwritable config directory for an existing config" , async ( ) => {
@@ -2827,7 +2830,7 @@ describe("doctor health contributions", () => {
28272830 ) . resolves . toMatchObject ( {
28282831 findings : [ ] ,
28292832 } ) ;
2830- expect ( accessSpy ) . toHaveBeenCalledWith ( "/tmp" , fs . constants . W_OK ) ;
2833+ expect ( accessSpy ) . toHaveBeenCalledWith ( "/tmp" , fs . constants . W_OK | fs . constants . X_OK ) ;
28312834 } ) ;
28322835
28332836 it ( "reports an unwritable existing parent when the config file is missing" , async ( ) => {
@@ -2858,6 +2861,36 @@ describe("doctor health contributions", () => {
28582861 } ) ;
28592862 } ) ;
28602863
2864+ it ( "reports an existing parent without search permission" , async ( ) => {
2865+ vi . spyOn ( fs , "existsSync" ) . mockImplementation ( ( path ) => path === "/tmp" ) ;
2866+ vi . spyOn ( fs , "accessSync" ) . mockImplementation ( ( _path , mode ) => {
2867+ if ( mode === ( fs . constants . W_OK | fs . constants . X_OK ) ) {
2868+ throw new Error ( "EACCES" ) ;
2869+ }
2870+ } ) ;
2871+
2872+ await expect (
2873+ runDoctorLintChecks (
2874+ {
2875+ cfg : { } ,
2876+ mode : "lint" as const ,
2877+ runtime : { log : vi . fn ( ) , error : vi . fn ( ) , exit : vi . fn ( ) } ,
2878+ configPath : "/tmp/openclaw-home/openclaw.json" ,
2879+ } ,
2880+ { checks : [ check ] , onlyIds : [ "core/doctor/write-config" ] } ,
2881+ ) ,
2882+ ) . resolves . toMatchObject ( {
2883+ findings : [
2884+ expect . objectContaining ( {
2885+ checkId : "core/doctor/write-config" ,
2886+ path : "/tmp" ,
2887+ target : "/tmp/openclaw-home" ,
2888+ requirement : "writable-config-directory" ,
2889+ } ) ,
2890+ ] ,
2891+ } ) ;
2892+ } ) ;
2893+
28612894 it ( "reports an existing file that blocks the config directory path" , async ( ) => {
28622895 vi . spyOn ( fs , "existsSync" ) . mockImplementation ( ( path ) => path === "/tmp/openclaw-home" ) ;
28632896 vi . spyOn ( fs , "statSync" ) . mockReturnValue ( {
0 commit comments