{"record":{"id":"668011bd781f37f7","repo":"multica-ai/multica","slug":"parse-config-toml-before-shell-environment-update","errorCode":null,"errorMessage":"parse config.toml before shell environment update: %w","messagePattern":"parse config\\.toml before shell environment update: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/internal/daemon/execenv/codex_shell_env.go","lineNumber":150,"sourceCode":"\treturn b.String(), nil\n}\n\n// stripUserShellEnvPolicy removes complete TOML expressions that define a\n// shell_environment_policy, including root dotted/inline values, quoted table\n// forms, nested set tables, and profile overlays. It deliberately preserves\n// comments and every unrelated expression byte-for-byte.\nfunc stripUserShellEnvPolicy(content []byte) ([]byte, error) {\n\tif len(bytes.TrimSpace(content)) == 0 {\n\t\treturn content, nil\n\t}\n\n\t// The iterative parser exposes source ranges but does not enforce all TOML\n\t// semantic rules (for example duplicate definitions). Validate with the\n\t// stable decoder first so a malformed user config is never partially\n\t// rewritten into a different malformed config.\n\tvar decoded map[string]any\n\tif err := toml.Unmarshal(content, &decoded); err != nil {\n\t\treturn nil, fmt.Errorf(\"parse config.toml before shell environment update: %w\", err)\n\t}\n\n\tvar parser unstable.Parser\n\tparser.Reset(content)\n\tvar currentTable []string\n\tranges := make([]tomlByteRange, 0, 8)\n\tfor parser.NextExpression() {\n\t\texpr := parser.Expression()\n\t\tkeys := tomlNodeKeys(expr)\n\t\tswitch expr.Kind {\n\t\tcase unstable.Table, unstable.ArrayTable:\n\t\t\tcurrentTable = keys\n\t\t\tif isCodexShellEnvPolicyPath(keys) {\n\t\t\t\tr, err := tomlTableHeaderLineRange(content, expr)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tranges = append(ranges, r)","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/internal/daemon/execenv/codex_shell_env.go#L132-L168","documentation":"stripUserShellEnvPolicy decodes the whole config.toml with the stable TOML decoder before doing byte-range surgery, so a malformed user config is never partially rewritten into a different malformed config. This error means the user's config.toml is syntactically invalid TOML — duplicate keys, bad syntax, mismatched brackets.","triggerScenarios":"A task or user hand-edited config.toml with a TOML syntax error or duplicate table definition; truncation from a crashed editor.","commonSituations":"Tasks that rewrite their own config.toml; manually provisioned shared home with typos; partial writes from disk-full incidents.","solutions":["Run a TOML validator on the config.toml named in the error context","Fix or remove the offending lines (often duplicate keys or unclosed strings)","Delete config.toml to let the daemon regenerate the managed blocks"],"exampleFix":"# before (invalid)\n[shell_environment_policy]\ninherit = \"all\"\ninherit = \"core\"   # duplicate key\n\n# after\n[shell_environment_policy]\ninherit = \"all\"","handlingStrategy":"validation","validationCode":"var probe map[string]any\nif err := toml.Unmarshal(raw, &probe); err != nil {\n\treturn fmt.Errorf(\"user config.toml is invalid TOML: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := stripUserShellEnvPolicy(content); err != nil {\n\tif strings.Contains(err.Error(), \"parse config.toml before shell environment update\") {\n\t\t// surface the syntax error to the user with line/column from the decoder\n\t}\n}","preventionTips":["Validate user-edited config.toml with a TOML linter before tasks run","Let the daemon regenerate config.toml instead of hand-editing it in task homes"],"tags":["toml","config","validation","codex"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}