multica-ai/multica · error
parse config.toml before shell environment update: %w
Error message
parse config.toml before shell environment update: %w
What it means
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.
Source
Thrown at server/internal/daemon/execenv/codex_shell_env.go:150
return b.String(), nil
}
// stripUserShellEnvPolicy removes complete TOML expressions that define a
// shell_environment_policy, including root dotted/inline values, quoted table
// forms, nested set tables, and profile overlays. It deliberately preserves
// comments and every unrelated expression byte-for-byte.
func stripUserShellEnvPolicy(content []byte) ([]byte, error) {
if len(bytes.TrimSpace(content)) == 0 {
return content, nil
}
// The iterative parser exposes source ranges but does not enforce all TOML
// semantic rules (for example duplicate definitions). Validate with the
// stable decoder first so a malformed user config is never partially
// rewritten into a different malformed config.
var decoded map[string]any
if err := toml.Unmarshal(content, &decoded); err != nil {
return nil, fmt.Errorf("parse config.toml before shell environment update: %w", err)
}
var parser unstable.Parser
parser.Reset(content)
var currentTable []string
ranges := make([]tomlByteRange, 0, 8)
for parser.NextExpression() {
expr := parser.Expression()
keys := tomlNodeKeys(expr)
switch expr.Kind {
case unstable.Table, unstable.ArrayTable:
currentTable = keys
if isCodexShellEnvPolicyPath(keys) {
r, err := tomlTableHeaderLineRange(content, expr)
if err != nil {
return nil, err
}
ranges = append(ranges, r)View on GitHub (pinned to 2c0912b6ec)
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
Example fix
# before (invalid) [shell_environment_policy] inherit = "all" inherit = "core" # duplicate key # after [shell_environment_policy] inherit = "all"
Defensive patterns
Strategy: validation
Validate before calling
var probe map[string]any
if err := toml.Unmarshal(raw, &probe); err != nil {
return fmt.Errorf("user config.toml is invalid TOML: %w", err)
} Try / catch
if err := stripUserShellEnvPolicy(content); err != nil {
if strings.Contains(err.Error(), "parse config.toml before shell environment update") {
// surface the syntax error to the user with line/column from the decoder
}
} Prevention
- 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
When it happens
Trigger: A task or user hand-edited config.toml with a TOML syntax error or duplicate table definition; truncation from a crashed editor.
Common situations: Tasks that rewrite their own config.toml; manually provisioned shared home with typos; partial writes from disk-full incidents.
Related errors
- render shell_environment_policy: %w
- parse config.toml shell environment expressions: %w
- config must be a JSON object
- config must not be empty
- entry must be a JSON object
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/668011bd781f37f7.
Report an issue: GitHub.