{"record":{"id":"485e2f121cf7b9e7","repo":"chenhg5/cc-connect","slug":"runisolationprobe-runasuser-is-empty","errorCode":null,"errorMessage":"RunIsolationProbe: RunAsUser is empty","messagePattern":"RunIsolationProbe: RunAsUser is empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/runas_audit.go","lineNumber":168,"sourceCode":"\tRunner     SudoRunner\n\t// ProbeScriptOverride, if non-nil, replaces the embedded probe\n\t// script. Tests use this; production always uses the embedded one.\n\tProbeScriptOverride []byte\n\tTimeout             time.Duration\n}\n\n// RunIsolationProbe spawns the probe as the target user and parses its\n// output. Does not fail on non-zero exit from the probe — whatever it\n// managed to print is still parsed.\nfunc RunIsolationProbe(ctx context.Context, cfg AuditConfig) (IsolationReport, error) {\n\treport := IsolationReport{\n\t\tProject:   cfg.Project,\n\t\tRunAsUser: cfg.RunAsUser,\n\t\tWorkDir:   cfg.WorkDir,\n\t\tTimestamp: time.Now().UTC(),\n\t}\n\tif cfg.RunAsUser == \"\" {\n\t\treturn report, errors.New(\"RunIsolationProbe: RunAsUser is empty\")\n\t}\n\tif cfg.Runner == nil {\n\t\tcfg.Runner = ExecSudoRunner{}\n\t}\n\tif cfg.Timeout == 0 {\n\t\tcfg.Timeout = 15 * time.Second\n\t}\n\tscript := cfg.ProbeScriptOverride\n\tif script == nil {\n\t\tscript = runasProbeScript\n\t}\n\n\tprobeCtx, cancel := context.WithTimeout(ctx, cfg.Timeout)\n\tdefer cancel()\n\n\t// Build env injection: since sudo -i strips env, we pass the probe\n\t// inputs as SHELL VARIABLES by prepending `export` statements to the\n\t// script body. Values are pre-validated at config parse time so","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/core/runas_audit.go#L150-L186","documentation":"RunIsolationProbe runs the deeper run_as_user isolation checks (work_dir access, escalation probes) and produces a report. It returns this error immediately when cfg.RunAsUser is empty because no probe can be executed without a target user. The result report is still returned alongside the error for the caller to log.","triggerScenarios":"runDoctorOne or an anonymous doctor worker calls RunIsolationProbe with a ProbeConfig whose RunAsUser field is the empty string (core/runas_audit.go:168).","commonSituations":"Running `cc-connect doctor user-isolation` against a project with no run_as_user configured; config parse left RunAsUser empty after a schema change; building the ProbeConfig programmatically and forgetting to populate RunAsUser.","solutions":["Configure run_as_user for the project in config.toml before running the doctor probe.","Skip the probe when RunAsUser is empty (the feature is disabled for that project).","Populate ProbeConfig.RunAsUser from the parsed project config before invoking RunIsolationProbe."],"exampleFix":"// before\nreport, err := core.RunIsolationProbe(ctx, cfg)\nif err != nil {\n    return err\n}\n// after\nif cfg.RunAsUser == \"\" {\n    return nil // run_as_user not configured; nothing to probe\n}\nreport, err := core.RunIsolationProbe(ctx, cfg)\nif err != nil {\n    return fmt.Errorf(\"doctor: isolation probe: %w\", err)\n}","handlingStrategy":"validation","validationCode":"if cfg.RunAsUser == \"\" {\n    return nil, nil // probe not applicable\n}","typeGuard":null,"tryCatchPattern":"report, err := core.RunIsolationProbe(ctx, cfg)\nif err != nil && cfg.RunAsUser != \"\" {\n    slog.Error(\"isolation probe failed\", \"err\", err)\n}","preventionTips":["Populate ProbeConfig.RunAsUser from validated project config before probing.","Fail config loading early when a project declares isolation intent but no user.","Add a doctor pre-check that lists projects missing run_as_user."],"tags":["config","sudo","isolation","doctor"],"backgroundTag":"missing-required-config-field","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"}