affaan-m/ECC · error

parse config %s: %w

Error message

parse config %s: %w

What it means

Wrapped error from LoadConfig in golang-patterns, raised on the JSON decode step. After the file is read successfully, json.Unmarshal(data, &cfg) is attempted; on failure the error is wrapped as fmt.Errorf("parse config %s: %w", path, err). This message specifically means: the file was readable but its contents could not be unmarshaled into the Config type.

Source

Thrown at skills/golang-patterns/SKILL.md:108

    // ...
}
```

## Error Handling Patterns

### Error Wrapping with Context

```go
// Good: Wrap errors with context
func LoadConfig(path string) (*Config, error) {
    data, err := os.ReadFile(path)
    if err != nil {
        return nil, fmt.Errorf("load config %s: %w", path, err)
    }

    var cfg Config
    if err := json.Unmarshal(data, &cfg); err != nil {
        return nil, fmt.Errorf("parse config %s: %w", path, err)
    }

    return &cfg, nil
}
```

### Custom Error Types

```go
// Define domain-specific errors
type ValidationError struct {
    Field   string
    Message string
}

func (e *ValidationError) Error() string {
    return fmt.Sprintf("validation failed on %s: %s", e.Field, e.Message)
}

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Run the file through a JSON validator or `jq .` to localize the syntax error.
  2. Compare the JSON keys against the Config struct fields and their json tags.
  3. Ensure the file is UTF-8 without a BOM and contains no comments.
  4. If multiple formats are possible, confirm the loader expects JSON for this path.

Example fix

// before
var cfg Config
if err := json.Unmarshal(data, &cfg); err != nil {
    return nil, fmt.Errorf("parse config %s: %w", path, err)
}

// after - surface line/column for easier diagnosis
var cfg Config
dec := json.NewDecoder(bytes.NewReader(data))
dec.DisallowUnknownFields()
if err := dec.Decode(&cfg); err != nil {
    return nil, fmt.Errorf("parse config %s at offset %d: %w", path, decodeOffset(data, dec), err)
}
Defensive patterns

Strategy: validation

Validate before calling

func validateConfigJSON(path string) error {
    data, err := os.ReadFile(path)
    if err != nil {
        return err
    }
    dec := json.NewDecoder(bytes.NewReader(data))
    dec.DisallowUnknownFields()
    var v map[string]any
    if err := dec.Decode(&v); err != nil {
        return fmt.Errorf("invalid JSON: %w", err)
    }
    return nil
}

Type guard

func isJSONTypeError(err error) bool {
    var te *json.UnmarshalTypeError
    var se *json.SyntaxError
    return errors.As(err, &te) || errors.As(err, &se)
}

Try / catch

cfg, err := LoadConfig(path)
if err != nil {
    var te *json.UnmarshalTypeError
    if errors.As(err, &te) {
        log.Fatalf("config field %s got wrong type: %v", te.Field, te)
    }
    var se *json.SyntaxError
    if errors.As(err, &se) {
        log.Fatalf("config syntax error at offset %d: %v", se.Offset, se)
    }
    log.Fatalf("load config: %v", err)
}

Prevention

When it happens

Trigger: Calling LoadConfig(path) where os.ReadFile succeeds but json.Unmarshal fails. Concrete triggers: the file content is not valid JSON (trailing comma, unquoted keys, single quotes, comments), a JSON value's type does not match the Go struct field, duplicate keys rejected by the decoder, or a BOM/control character breaks the parser.

Common situations: Hand-edited config with a trailing comma or comment; struct field renamed without updating the JSON; numbers passed where strings are expected (or vice versa); an encoding glitch introduced a BOM; the file was overwritten with YAML/TOML by mistake.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/b2e053d3dc484bba. Report an issue: GitHub.