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

  1. Run a TOML validator on the config.toml named in the error context
  2. Fix or remove the offending lines (often duplicate keys or unclosed strings)
  3. 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

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


AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15). Data as JSON: /api/errors/668011bd781f37f7. Report an issue: GitHub.