alibaba/open-code-review · error
unmarshal tools file: %w
Error message
unmarshal tools file: %w
What it means
Load successfully read the tools JSON but json.Unmarshal could not decode it into []ToolConfigEntry; the error wraps the decode failure. This indicates the file is malformed JSON or its structure does not match the expected array of tool entries.
Source
Thrown at internal/config/toolsconfig/toolsconfig.go:40
//go:embed tools.json
var defaultToolsJSON []byte
// Load parses the tools config file. When path is empty, falls back to
// the embedded default tools configuration.
func Load(path string) ([]ToolConfigEntry, error) {
var data []byte
var err error
if path == "" {
data = defaultToolsJSON
} else {
data, err = os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("read tools file %s: %w", path, err)
}
}
var tools []ToolConfigEntry
if err := json.Unmarshal(data, &tools); err != nil {
return nil, fmt.Errorf("unmarshal tools file: %w", err)
}
return tools, nil
}
// ToolDefsByPhase returns the parsed tool definitions filtered by phase.
// planOnly=true returns only tools with plan_task:true.
// planOnly=false returns only tools with main_task:true.
func (t *ToolConfigEntry) ToolDefsByPhase(planOnly bool) (json.RawMessage, bool) {
switch {
case planOnly && t.PlanTask:
return t.Definition, true
case !planOnly && t.MainTask:
return t.Definition, true
default:
return nil, false
}
}
View on GitHub (pinned to 5cf97d0d15)
Solutions
- Run the file through a JSON validator and fix syntax errors
- Compare the file structure against []ToolConfigEntry and fix field names/types
- Start from the built-in default tools JSON (pass empty path) and re-apply customizations
Example fix
// before
[{"name":"read_files","enabled":"yes"}] // wrong type
// after
[{"name":"read_files","enabled":true}] Defensive patterns
Strategy: validation
Validate before calling
var probe []toolsconfig.ToolConfigEntry
if err := json.Unmarshal(data, &probe); err != nil { return err } // pre-check before Load Try / catch
tools, err := toolsconfig.Load(path)
if err != nil {
var typeErr *json.UnmarshalTypeError
if errors.As(err, &typeErr) { return fmt.Errorf("tools schema mismatch at %s: %w", typeErr.Field, err) }
return err
} Prevention
- Lint tools JSON files in CI with the Go struct as the schema
- Version the tools file schema and check it on load
- Never hand-edit JSON without re-validating; start from the default file
When it happens
Trigger: Calling Load() (default bytes) or Load(path) where the JSON is syntactically invalid, is not an array, or entries have fields with mismatched types (e.g. string where bool expected).
Common situations: Hand-edited tools file with a trailing comma or unquoted key; a tools file written for an older schema version whose fields changed types; someone saved a YAML file with a .json extension.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- read path_rule_map value for %q: %w
- unmarshal global rule: %w
- unmarshal rule file %s: %w
- unmarshal task_template manifest: %w
- unmarshal default scan template: %w
AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02).
Data as JSON: /api/errors/ae5a1429156da9cd.
Report an issue: GitHub.