{"record":{"id":"53a1930e5bf5ee0b","repo":"chenhg5/cc-connect","slug":"work-dir-is-not-a-directory-s","errorCode":null,"errorMessage":"work_dir is not a directory: %s","messagePattern":"work_dir is not a directory: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/setup.go","lineNumber":526,"sourceCode":"\t\t\"restart_required\": true,\n\t})\n}\n\nfunc validateProjectWorkDir(workDir string) (string, error) {\n\ttrimmed := strings.TrimSpace(workDir)\n\tif trimmed == \"\" {\n\t\treturn \"\", nil\n\t}\n\n\tinfo, err := os.Stat(trimmed)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\treturn \"\", fmt.Errorf(\"work_dir does not exist: %s\", trimmed)\n\t\t}\n\t\treturn \"\", fmt.Errorf(\"work_dir is not accessible: %s: %w\", trimmed, err)\n\t}\n\tif !info.IsDir() {\n\t\treturn \"\", fmt.Errorf(\"work_dir is not a directory: %s\", trimmed)\n\t}\n\treturn trimmed, nil\n}\n","sourceCodeStart":508,"sourceCodeEnd":530,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/core/setup.go#L508-L530","documentation":"validateProjectWorkDir throws this when the path exists (os.Stat succeeds) but is a regular file (or other non-directory) rather than a directory. Agents need a working directory, so a file path is rejected.","triggerScenarios":"Pointing work_dir at a file such as config.toml, a binary, a symlink to a file, or accidentally pasting a file path into the project setup form (handleProjectDetail, handleProjectAddPlatform, setup save handlers).","commonSituations":"Copy-pasting a file path instead of the folder; tab-completion stopping one component short; macOS paths like /Users/me/project/file vs the project dir; work_dir accidentally set to the config file itself.","solutions":["Change work_dir to the containing directory of the intended path","Verify with `test -d <path> && echo dir` or `ls -ld <path>` before saving","If a symlink is involved, confirm it resolves to a directory (readlink -f)"],"exampleFix":"// before\nwork_dir = \"/home/alice/app/docker-compose.yml\"\n// after\nwork_dir = \"/home/alice/app\"","handlingStrategy":"validation","validationCode":"wd := strings.TrimSpace(cfg.WorkDir)\ninfo, err := os.Stat(wd)\nswitch {\ncase err != nil:\n    return fmt.Errorf(\"stat %s: %w\", wd, err)\ncase !info.IsDir():\n    return fmt.Errorf(\"%s is a file; use its parent directory\", wd)\n}","typeGuard":"func isDir(path string) bool {\n    info, err := os.Stat(path)\n    return err == nil && info.IsDir()\n}","tryCatchPattern":"dir, err := validateProjectWorkDir(cfg.WorkDir)\nif err != nil {\n    if strings.Contains(err.Error(), \"not a directory\") {\n        dir = filepath.Dir(strings.TrimSpace(cfg.WorkDir))\n        slog.Warn(\"work_dir was a file; using parent\", \"dir\", dir)\n    } else { return err }\n}","preventionTips":["Validate with `test -d` (or a stat call) before pasting a path into project setup","Beware symlinks: confirm the resolved target is a directory with readlink -f","Watch for tab-completion landing on a file inside the intended project folder"],"tags":["config","filesystem","directory"],"backgroundTag":"path-is-not-a-directory","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}