{"record":{"id":"6c290e2ac2208391","repo":"multica-ai/multica","slug":"read-config-toml-w","errorCode":null,"errorMessage":"read config.toml: %w","messagePattern":"read config\\.toml: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/internal/daemon/execenv/codex_sandbox.go","lineNumber":443,"sourceCode":"\t\t}\n\t\tout = append(out, line)\n\t}\n\treturn strings.Join(out, \"\\n\")\n}\n\n// ensureCodexSandboxConfig writes the multica-managed sandbox block into the\n// given config.toml according to the policy. It is idempotent: running it\n// twice produces the same file contents. The file is created if it doesn't\n// exist.\n//\n// The function logs (at warn level) whenever the resolved mode is\n// danger-full-access — the Linux default, the macOS seatbelt fallback, and the\n// Windows no-native-sandbox fallback alike — so that every unsandboxed task is\n// visible in daemon logs.\nfunc ensureCodexSandboxConfig(configPath string, policy codexSandboxPolicy, detectedVersion string, logger *slog.Logger) error {\n\tdata, err := os.ReadFile(configPath)\n\tif err != nil && !os.IsNotExist(err) {\n\t\treturn fmt.Errorf(\"read config.toml: %w\", err)\n\t}\n\texisting := string(data)\n\n\t// Drop inline sandbox_mode / [sandbox_workspace_write] from older daemon\n\t// versions so they don't collide with the managed block.\n\tif existing != \"\" && !managedBlockRe.MatchString(existing) {\n\t\texisting = stripLegacySandboxDirectives(existing)\n\t}\n\n\tupdated := upsertMulticaManagedBlock(existing, policy)\n\tif updated == string(data) {\n\t\treturn nil\n\t}\n\n\tif policy.Mode == \"danger-full-access\" && logger != nil {\n\t\tversion := detectedVersion\n\t\tif version == \"\" {\n\t\t\tversion = \"unknown\"","sourceCodeStart":425,"sourceCodeEnd":461,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/internal/daemon/execenv/codex_sandbox.go#L425-L461","documentation":"ensureCodexSandboxConfig reads the task's config.toml before upserting the managed sandbox block. A missing file is fine (it is created), but any other read error — permissions, I/O failure, or the path being a directory — aborts sandbox configuration so an unmanaged config is never silently accepted.","triggerScenarios":"config.toml exists but is unreadable by the daemon user; the path names a directory; disk I/O error during read.","commonSituations":"Task home restored from archive with wrong ownership; a task made config.toml mode 000; corrupted volume.","solutions":["Fix ownership/permissions on the task home's config.toml","Delete the unreadable config.toml — it will be recreated with the managed block","Recreate the task home if state is suspect"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if fi, err := os.Stat(configPath); err == nil && !fi.Mode().IsRegular() {\n\treturn fmt.Errorf(\"config.toml path is not a regular file\")\n}","typeGuard":null,"tryCatchPattern":"if err := ensureCodexSandboxConfig(...); err != nil {\n\tif strings.Contains(err.Error(), \"read config.toml\") && !errors.Is(err, fs.ErrPermission) {\n\t\t// missing file is fine; anything else needs operator attention\n\t}\n}","preventionTips":["Ensure daemon ownership of task-home config files","Delete unreadable config.toml files rather than forcing prepare"],"tags":["filesystem","config","codex","sandbox"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}