{"record":{"id":"8e976d6a5d8659bd","repo":"chenhg5/cc-connect","slug":"write-task-script-w","errorCode":null,"errorMessage":"write task script: %w","messagePattern":"write task script: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"daemon/windows.go","lineNumber":58,"sourceCode":"func (*schtasksManager) Platform() string { return \"schtasks\" }\n\nfunc (m *schtasksManager) Install(cfg Config) error {\n\tif err := os.MkdirAll(DefaultDataDir(), 0755); err != nil {\n\t\treturn fmt.Errorf(\"create data dir: %w\", err)\n\t}\n\tif err := os.MkdirAll(filepath.Dir(cfg.LogFile), 0755); err != nil {\n\t\treturn fmt.Errorf(\"create log dir: %w\", err)\n\t}\n\n\tscriptPath := windowsTaskScriptPath()\n\t// 0644 has weak semantics on Windows; the file ACL is what matters.\n\t// We still write 0600 so the file's POSIX bits do not advertise read\n\t// access, and rely on the user's own profile ACLs for primary defense\n\t// (the script lives under %USERPROFILE%\\.cc-connect by default).\n\t// WriteFile only applies perm on create, so Chmod the existing file\n\t// after writing to harden reinstalls of pre-existing 0644 scripts.\n\tif err := os.WriteFile(scriptPath, []byte(buildWindowsTaskScript(cfg)), 0600); err != nil {\n\t\treturn fmt.Errorf(\"write task script: %w\", err)\n\t}\n\tif err := os.Chmod(scriptPath, 0600); err != nil {\n\t\treturn fmt.Errorf(\"chmod task script: %w\", err)\n\t}\n\n\tif err := stopWindowsTask(); err != nil {\n\t\tslog.Warn(\"schtasks: stop existing task failed\", \"error\", err)\n\t}\n\tif err := deleteWindowsTask(); err != nil {\n\t\tif windowsTaskMatchesAction(scriptPath) {\n\t\t\tif err := m.Start(); err != nil {\n\t\t\t\treturn fmt.Errorf(\"start existing task: %w\", err)\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\t\treturn err\n\t}\n","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/daemon/windows.go#L40-L76","documentation":"schtasksManager.Install writes the helper script that the scheduled task will execute (buildWindowsTaskScript(cfg)) to a path under the data dir with os.WriteFile(..., 0600); failure is wrapped as \"write task script: %w\". This happens after both directories were created successfully, so it usually indicates an ACL/permission or disk problem on the script file itself rather than a missing directory.","triggerScenarios":"`cc-connect daemon install` when os.WriteFile on windowsTaskScriptPath() fails: the existing script file is read-only or locked by another process, ACL denies write, the volume is full or read-only, or antivirus blocks writing .ps1/.bat-style scripts.","commonSituations":"A previous 0644/read-only script left by an old install; an editor or the scheduled task itself holding the script open; Controlled Folder Access (Defender ransomware protection) blocking writes to protected folders; disk quota/full disk.","solutions":["Delete or unlock the existing script file at windowsTaskScriptPath() (under %USERPROFILE%\\.cc-connect) and rerun install","Check the wrapped cause: \"Access is denied\" → fix ACLs or Controlled Folder Access exclusions; \"being used by another process\" → stop the task/process holding it","Ensure the target volume has free space and is not read-only","If antivirus blocks script creation, add an exclusion for the cc-connect data directory"],"exampleFix":"// before\n$ cc-connect daemon install\n// error: write task script: open ...: Access is denied.\n// after\n> del %USERPROFILE%\\.cc-connect\\cc-connect-task.ps1\n> cc-connect daemon install","handlingStrategy":"retry","validationCode":"scriptPath := filepath.Join(os.Getenv(\"USERPROFILE\"), \".cc-connect\", \"cc-connect-task.ps1\")\nif f, err := os.OpenFile(scriptPath, os.O_WRONLY, 0o600); err != nil {\n    log.Fatalf(\"script not writable (%v); delete %s or stop the task holding it open before install\", err, scriptPath)\n} else {\n    f.Close()\n}","typeGuard":null,"tryCatchPattern":"if err := daemon.Install(cfg); err != nil && strings.Contains(err.Error(), \"write task script\") {\n    time.Sleep(500 * time.Millisecond) // transient lock by running task/AV scan\n    if retryErr := daemon.Install(cfg); retryErr != nil {\n        return fmt.Errorf(\"stop the running task or remove the read-only script, then retry: %w\", retryErr)\n    }\n    return nil\n}","preventionTips":["Stop/unregister the old scheduled task before reinstalling so the script is not locked","Remove read-only attributes from files in %USERPROFILE%\\.cc-connect before upgrades","Add the cc-connect data directory to antivirus/Controlled Folder Access exclusions","Keep free disk space and avoid installing from read-only mounts"],"tags":["windows","filesystem","file-write","permissions","daemon"],"backgroundTag":"file-write-failed","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"}