chenhg5/cc-connect · error

create data dir: %w

Error message

create data dir: %w

What it means

schtasksManager.Install (Windows) first ensures cc-connect's data directory exists via os.MkdirAll(DefaultDataDir(), 0755) and wraps any failure as "create data dir: %w". It fires when the directory cannot be created or verified — typically a permission problem, an invalid path, or a non-directory file occupying the path. The wrapped original error (e.g. access is denied) is preserved for diagnosis.

Source

Thrown at daemon/windows.go:44

func strictPowerShell(script string) string {
	return "$ErrorActionPreference = 'Stop'\n" + script
}

type schtasksManager struct{}

func newPlatformManager() (Manager, error) {
	if _, err := exec.LookPath("powershell.exe"); err != nil {
		return nil, fmt.Errorf("powershell.exe not found: Windows Task Scheduler management requires PowerShell")
	}
	return &schtasksManager{}, nil
}

func (*schtasksManager) Platform() string { return "schtasks" }

func (m *schtasksManager) Install(cfg Config) error {
	if err := os.MkdirAll(DefaultDataDir(), 0755); err != nil {
		return fmt.Errorf("create data dir: %w", err)
	}
	if err := os.MkdirAll(filepath.Dir(cfg.LogFile), 0755); err != nil {
		return fmt.Errorf("create log dir: %w", err)
	}

	scriptPath := windowsTaskScriptPath()
	// 0644 has weak semantics on Windows; the file ACL is what matters.
	// We still write 0600 so the file's POSIX bits do not advertise read
	// access, and rely on the user's own profile ACLs for primary defense
	// (the script lives under %USERPROFILE%\.cc-connect by default).
	// WriteFile only applies perm on create, so Chmod the existing file
	// after writing to harden reinstalls of pre-existing 0644 scripts.
	if err := os.WriteFile(scriptPath, []byte(buildWindowsTaskScript(cfg)), 0600); err != nil {
		return fmt.Errorf("write task script: %w", err)
	}
	if err := os.Chmod(scriptPath, 0600); err != nil {
		return fmt.Errorf("chmod task script: %w", err)
	}

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Check the wrapped cause in the error text (e.g. "Access is denied") and fix that underlying ACL or path problem first
  2. Run the install from an interactive account with a real %USERPROFILE%, or pre-create %USERPROFILE%\.cc-connect manually with correct permissions
  3. Verify the path is not occupied by a file: `dir %USERPROFILE%` — rename/remove any entry named `.cc-connect` that is a file
  4. If USERPROFILE points to a missing drive, correct the environment variable or the profile for the account

Example fix

// before
$ cc-connect daemon install
// error: create data dir: mkdir ...: Access is denied.
// after: pre-create with correct ACL
> mkdir %USERPROFILE%\.cc-connect
> icacls %USERPROFILE%\.cc-connect /grant "%USERNAME%:(OI)(CI)F"
> cc-connect daemon install
Defensive patterns

Strategy: validation

Validate before calling

dataDir := os.UserHomeDir() + "\\.cc-connect"
if st, err := os.Stat(dataDir); err == nil && !st.IsDir() {
    log.Fatalf("%s exists but is a file; remove or rename it before daemon install", dataDir)
}
if err := os.MkdirAll(dataDir, 0o755); err != nil {
    log.Fatalf("cannot create data dir %s: %v — fix ACLs/profile before install", dataDir, err)
}

Try / catch

if err := daemon.Install(cfg); err != nil {
    var pe *fs.PathError
    if errors.As(err, &pe) && strings.Contains(err.Error(), "create data dir") {
        return fmt.Errorf("check permissions/ACLs on %s and that USERPROFILE is valid: %w", pe.Path, err)
    }
    return err
}

Prevention

When it happens

Trigger: Running `cc-connect daemon install` on Windows when the default data dir (under %USERPROFILE%\.cc-connect) cannot be MkdirAll'd: read-only or redirected USERPROFILE, antivirus/ACL denial, or DefaultDataDir() resolving to a drive letter that does not exist.

Common situations: Installing as a service account whose profile is not provisioned (TEMP-profile services); roaming profiles with deny ACLs; running from a sandboxed/readonly environment; a stale file named `.cc-connect` sitting in the profile root.

Understand the failure class

Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/086b2e335c38f6c0. Report an issue: GitHub.