tomnomnom/gron · error

cannot merge object with non-object

Error message

cannot merge object with non-object

What it means

recursiveMerge was asked to merge a map[string]interface{} with a value whose dynamic type is not a map, which cannot be combined. This means two parsed statements assign both an object and a scalar/array to the same key path in the input.

Source

Thrown at ungron.go:449

		// There needs to be at least key + 1 space in the array
		out := make([]interface{}, key+1)
		out[key] = val
		return out, nil

	default:
		return nil, fmt.Errorf("unexpected token `%s`", t.text)
	}
}

// recursiveMerge merges maps and slices, or returns b for scalars
func recursiveMerge(a, b interface{}) (interface{}, error) {
	switch a.(type) {

	case map[string]interface{}:
		bMap, ok := b.(map[string]interface{})
		if !ok {
			return nil, fmt.Errorf("cannot merge object with non-object")
		}
		return recursiveMapMerge(a.(map[string]interface{}), bMap)

	case []interface{}:
		bSlice, ok := b.([]interface{})
		if !ok {
			return nil, fmt.Errorf("cannot merge array with non-array")
		}
		return recursiveSliceMerge(a.([]interface{}), bSlice)

	case string, int, float64, bool, nil, json.Number:
		// Can't merge them, second one wins
		return b, nil

	default:
		return nil, fmt.Errorf("unexpected data type for merge: `%s`", reflect.TypeOf(a))
	}
}

View on GitHub (pinned to 88a6234ea2)

Solutions

  1. Make the input consistent so a given key path is always an object whenever it is assigned an object anywhere
  2. Split conflicting statements across distinct key paths
Defensive patterns

Strategy: type-guard

When it happens

Trigger: Thrown at ungron.go:449 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of tomnomnom/gron@88a6234ea2 (2026-09-06). Data as JSON: /api/errors/d7258e4bc2575592. Report an issue: GitHub.