{"record":{"id":"5895d17bd5f960e6","repo":"chenhg5/cc-connect","slug":"cannot-create-config-directory-w-5895d1","errorCode":null,"errorMessage":"cannot create config directory: %w","messagePattern":"cannot create config directory: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/cc-connect/instance_lock_windows.go","lineNumber":31,"sourceCode":"const killWaitTimeout = 5 * time.Second\nconst killWaitInterval = 25 * time.Millisecond\n\nconst processQueryLimitedInformation = 0x1000\n\ntype InstanceLock struct {\n\thandle   syscall.Handle\n\tpath     string\n\tacquired bool\n}\n\nfunc AcquireInstanceLock(configPath string) (*InstanceLock, error) {\n\tconfigDir := filepath.Dir(configPath)\n\tconfigBase := filepath.Base(configPath)\n\tlockName := fmt.Sprintf(\".%s.lock\", configBase)\n\tlockPath := filepath.Join(configDir, lockName)\n\n\tif err := os.MkdirAll(configDir, 0755); err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot create config directory: %w\", err)\n\t}\n\n\tpathPtr, err := syscall.UTF16PtrFromString(lockPath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot convert lock path: %w\", err)\n\t}\n\n\thandle, createErr := syscall.CreateFile(\n\t\tpathPtr,\n\t\tsyscall.GENERIC_READ|syscall.GENERIC_WRITE,\n\t\tsyscall.FILE_SHARE_READ,\n\t\tnil,\n\t\tsyscall.OPEN_ALWAYS,\n\t\tsyscall.FILE_ATTRIBUTE_NORMAL,\n\t\t0,\n\t)\n\n\tif createErr != nil {","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/cmd/cc-connect/instance_lock_windows.go#L13-L49","documentation":"Windows build of AcquireInstanceLock: os.MkdirAll on the config directory failed, producing \"cannot create config directory: %w\" before any Win32 lock APIs are invoked. Causes are the usual Windows filesystem errors: access denied, path occupied by a file, invalid path characters, or read-only media.","triggerScenarios":"Calling AcquireInstanceLock(configPath) on Windows where filepath.Dir(configPath) cannot be created: ACL denies write, a file exists at the directory path, path length limits (MAX_PATH) exceeded, or the drive is read-only/full.","commonSituations":"Config placed under C:\\Program Files (needs admin), path > 260 characters, running as a service account without a writable profile directory, or OneDrive-synced folder locked.","solutions":["Move the config to a user-writable location (e.g. %APPDATA%\\cc-connect\\config.toml).","Check ACLs on the parent directory (icacls <dir>) and grant the running user modify rights.","Enable long-path support or shorten the path if MAX_PATH is exceeded.","Check drive space and read-only attribute of the volume."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"dir := filepath.Dir(configPath)\nif fi, err := os.Stat(dir); err == nil && !fi.IsDir() {\n    return fmt.Errorf(\"%s is a file\", dir)\n}\nif err := os.MkdirAll(dir, 0755); err != nil {\n    return fmt.Errorf(\"config dir not creatable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"lock, err := AcquireInstanceLock(configPath)\nif err != nil && strings.Contains(err.Error(), \"cannot create config directory\") {\n    slog.Error(\"Windows: check ACLs/path length/drive state\", \"dir\", dir, \"err\", err)\n    os.Exit(1)\n}","preventionTips":["Install configs under %APPDATA%, not Program Files.","Keep paths under 260 chars or enable long paths (LongPathsEnabled).","Grant the service account modify rights on the config directory."],"tags":["windows","filesystem","permissions","mkdir","cli"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}