crowdsecurity/crowdsec · error

unable to dump metas: %w

Error message

unable to dump metas: %w

What it means

TruncateContext first JSON-marshals the whole []string value to measure its size against contextValueLen. If that initial json.Marshal fails, it returns 'unable to dump metas: %w'. The function's contract is that a context value must be serializable to JSON since the alert metadata is stored/transmitted as a JSON string.

Source

Thrown at pkg/alertcontext/alertcontext.go:131

			errors = append(errors, fmt.Errorf("error truncating content for %s: %w", key, err))
			continue
		}

		meta := models.MetaItems0{
			Key:   key,
			Value: valueStr,
		}
		metas = append(metas, &meta)
	}

	return metas, errors
}

// Truncate an individual []string to fit in the context value length
func TruncateContext(values []string, contextValueLen int) (string, error) {
	valueByte, err := json.Marshal(values)
	if err != nil {
		return "", fmt.Errorf("unable to dump metas: %w", err)
	}

	ret := string(valueByte)
	for len(ret) > contextValueLen {
		// if there is only 1 value left and that the size is too big, truncate it
		if len(values) == 1 {
			valueToTruncate := values[0]
			half := len(valueToTruncate) / 2
			lastValueTruncated := valueToTruncate[:half] + "..."
			values = values[:len(values)-1]
			values = append(values, lastValueTruncated)
		} else {
			// if there is multiple value inside, just remove the last one
			values = values[:len(values)-1]
		}

		valueByte, err = json.Marshal(values)
		if err != nil {

View on GitHub (pinned to 909b515798)

Solutions

  1. Examine the wrapped error to understand the marshal failure
  2. Ensure values passed to TruncateContext are []string
  3. If it reproduces with valid []string input, file a bug — it indicates an internal invariant violation
  4. Keep context values as plain UTF-8 strings in configuration and evaluation
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := json.Marshal(values); err != nil {
    return fmt.Errorf("values not marshallable: %w", err)
}

Type guard

func isStringSlice(v any) bool {
    _, ok := v.([]string)
    return ok
}

Try / catch

s, err := alertcontext.TruncateContext(values, maxLen)
if err != nil {
    log.Errorf("truncate failed: %v", err)
    s = "[]" // safe fallback
}

Prevention

When it happens

Trigger: Called from TruncateContextMap with a values slice that cannot be marshaled. For plain []string this marshal cannot realistically fail; it is a defensive guard that would only trigger with a nil-vs-type anomaly or if the function were reused with other slice types.

Common situations: Practically unreachable in normal operation with []string inputs; encountered only if internals change or values somehow contain non-serializable content.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/220223d058121a88. Report an issue: GitHub.