{"record":{"id":"f4c0d83c3c1b7bf1","repo":"chenhg5/cc-connect","slug":"project-q-preflight-w","errorCode":null,"errorMessage":"project %q preflight: %w","messagePattern":"project %q preflight: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/cc-connect/runas_startup.go","lineNumber":130,"sourceCode":"\t\t\t\tSupervisor: supervisor,\n\t\t\t\tRunner:     runner,\n\t\t\t})\n\t\t\toutcomes[i].audit = report\n\t\t\toutcomes[i].auditErr = err\n\t\t}()\n\t}\n\twg.Wait()\n\n\t// Log every outcome — warnings, fatals, and clean passes — so the\n\t// operator has a single visible record of what was checked.\n\tvar fatals []error\n\tfor _, o := range outcomes {\n\t\tfor _, w := range o.preflight.Warnings {\n\t\t\tslog.Warn(\"run_as_user: preflight warning\", \"project\", o.project, \"message\", w)\n\t\t}\n\t\tfor _, f := range o.preflight.Fatal {\n\t\t\tslog.Error(\"run_as_user: preflight FATAL\", \"project\", o.project, \"error\", f)\n\t\t\tfatals = append(fatals, fmt.Errorf(\"project %q preflight: %w\", o.project, f))\n\t\t}\n\t\tif o.preflight.HasFatal() {\n\t\t\tcontinue\n\t\t}\n\t\tif o.auditErr != nil {\n\t\t\tslog.Error(\"run_as_user: isolation probe failed to run\",\n\t\t\t\t\"project\", o.project, \"error\", o.auditErr)\n\t\t\tfatals = append(fatals, fmt.Errorf(\"project %q probe: %w\", o.project, o.auditErr))\n\t\t\tcontinue\n\t\t}\n\t\tslog.Info(\"run_as_user: isolation audit completed\",\n\t\t\t\"project\", o.project,\n\t\t\t\"whoami\", o.audit.Identity.Whoami,\n\t\t\t\"workdir_writable\", o.audit.WorkDirStatus.Writable,\n\t\t\t\"target_paths\", len(o.audit.TargetPaths),\n\t\t\t\"cross_user_results\", len(o.audit.CrossUser),\n\t\t)\n\t\tfor _, f := range o.audit.Fatal {","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/cmd/cc-connect/runas_startup.go#L112-L148","documentation":"runRunAsUserStartupChecks aggregates per-project results for the run_as_user mode. If a project's preflight check reports a Fatal item, it is logged and wrapped as `project %q preflight: %w` into the fatals list. This means the project cannot safely start under the run-as user.","triggerScenarios":"A configured project fails its preflight (e.g. workdir not writable by the run-as user, missing binary, bad permissions) so preflight.Fatal is non-empty during startup checks.","commonSituations":"Run_as_user deployed with a project whose working directory is owned by root; CLI binary not executable by the service user; config path permissions too strict after hardening.","solutions":["Read the preceding 'run_as_user: preflight FATAL' log line for the exact underlying error for that project.","Fix the reported condition (chmod/chown workdir, make the agent CLI executable for the run-as user).","Re-run startup; the error names the project so only failing projects need fixing."],"exampleFix":"// before\nsudo chown root:root /srv/myproject  # run-as user cannot write\n// after\nsudo chown runasuser:runasuser /srv/myproject && chmod u+wx /srv/myproject","handlingStrategy":"validation","validationCode":"// pre-deploy check\nsudo -u \"$RUNAS_USER\" test -w \"$PROJECT_WORKDIR\" || echo \"workdir not writable by $RUNAS_USER\"","typeGuard":null,"tryCatchPattern":"if err := runRunAsUserStartupChecks(ctx); err != nil {\n    slog.Error(\"startup aborted\", \"err\", err)\n    os.Exit(1) // keep detailed FATAL lines in logs\n}","preventionTips":["Provision project workdirs with correct ownership before enabling run_as_user.","Run a dry-run of preflight checks after any user/permission change.","Keep the agent CLI binaries world-executable or owned by the run-as user."],"tags":["go","startup","preflight","permissions"],"backgroundTag":"permission-denied","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"}