{"record":{"id":"e12d37ce66c9b31b","repo":"chenhg5/cc-connect","slug":"qodersession-start-w","errorCode":null,"errorMessage":"qoderSession: start: %w","messagePattern":"qoderSession: start: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/qoder/session.go","lineNumber":131,"sourceCode":"\n\tslog.Debug(\"qoderSession: launching\", \"resume\", sid != \"\", \"args_len\", len(args))\n\n\tcmd := exec.CommandContext(qs.ctx, qs.cmd, args...)\n\tcmd.Dir = qs.workDir\n\tif len(qs.extraEnv) > 0 {\n\t\tcmd.Env = core.MergeEnv(os.Environ(), qs.extraEnv)\n\t}\n\n\tstdout, err := cmd.StdoutPipe()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"qoderSession: stdout pipe: %w\", err)\n\t}\n\n\tvar stderrBuf bytes.Buffer\n\tcmd.Stderr = &stderrBuf\n\n\tif err := cmd.Start(); err != nil {\n\t\treturn fmt.Errorf(\"qoderSession: start: %w\", err)\n\t}\n\n\tqs.wg.Add(1)\n\tgo qs.readLoop(cmd, stdout, &stderrBuf)\n\n\treturn nil\n}\n\nfunc (qs *qoderSession) readLoop(cmd *exec.Cmd, stdout io.ReadCloser, stderrBuf *bytes.Buffer) {\n\tdefer qs.wg.Done()\n\n\tvar gotResult bool\n\tvar nonJSONLines []string\n\n\tscanner := bufio.NewScanner(stdout)\n\tscanner.Buffer(make([]byte, 0, 64*1024), 10*1024*1024)\n\n\tfor scanner.Scan() {","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/agent/qoder/session.go#L113-L149","documentation":"Send in agent/qoder/session.go fails when cmd.Start() cannot launch the qoder CLI process; the OS-level cause (binary missing, permission denied, working directory nonexistent) is wrapped with %w. This happens after the pipes are set up, just before the readLoop goroutine starts.","triggerScenarios":"exec.LookPath passed at New() time but the binary was removed/changed since; the configured workDir does not exist or is not accessible; exec format/permission problems; resource limits (fork failure).","commonSituations":"Binary uninstalled or PATH altered between session creation and Send; workDir deleted while session alive (e.g. tmpdir cleanup); container without exec permission on the mount; ENOEXEC from a wrong-arch binary.","solutions":["Read the wrapped cause: ENOENT -> binary or workDir missing, EACCES -> permissions, ENOEXEC -> wrong binary format","Verify the qoder binary and workDir exist at Send time (os.Stat both)","Use an absolute binary path in config to avoid PATH drift","Check mount noexec flags and architecture of the installed CLI"],"exampleFix":"// before\nif _, err := os.Stat(qs.workDir); err != nil {\n    // Send will fail with start: chdir ...: no such file or directory\n}\n// after\nif _, err := os.Stat(qs.workDir); err != nil {\n    os.MkdirAll(qs.workDir, 0o755)\n}","handlingStrategy":"try-catch","validationCode":"if _, err := os.Stat(qs.workDir); err != nil {\n    os.MkdirAll(qs.workDir, 0o755)\n}\nif _, err := exec.LookPath(\"qodercli\"); err != nil {\n    return errors.New(\"qoder binary missing at send time\")\n}","typeGuard":null,"tryCatchPattern":"if err := session.Send(ctx, msg); err != nil {\n    if strings.Contains(err.Error(), \"start:\") {\n        slog.Error(\"qoder failed to start\", \"err\", err) // inspect wrapped ENOENT/EACCES/ENOEXEC\n    }\n    return err\n}","preventionTips":["Stat the binary and workDir before starting the process","Use absolute paths for cmd and workDir in config","Verify mounts are not noexec and the binary matches the arch","Re-validate the environment periodically in long-lived daemons"],"tags":["go","process","exec","filesystem"],"backgroundTag":"command-not-found","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"}