larksuite/cli · error

jq: unmarshal input: %w

Error message

jq: unmarshal input: %w

What it means

applyJQ must unmarshal the event's raw JSON payload into interface{} before running the compiled gojq expression; this error wraps the json.Unmarshal failure. The library throws it because a jq filter can only run on valid JSON — if the event payload is not parseable JSON, filtering cannot proceed and the event is rejected with this jq-prefixed error.

Source

Thrown at internal/event/consume/jq.go:34

func CompileJQ(expr string) (*gojq.Code, error) {
	query, err := gojq.Parse(expr)
	if err != nil {
		return nil, errs.NewValidationError(errs.SubtypeInvalidArgument,
			"invalid jq expression: %s", err).WithParam("--jq").WithCause(err)
	}
	code, err := gojq.Compile(query)
	if err != nil {
		return nil, errs.NewValidationError(errs.SubtypeInvalidArgument,
			"jq compile error: %s", err).WithParam("--jq").WithCause(err)
	}
	return code, nil
}

// applyJQ returns (nil, nil) when the expression filters out the event (e.g. select).
func applyJQ(code *gojq.Code, data json.RawMessage) (json.RawMessage, error) {
	var input interface{}
	if err := json.Unmarshal(data, &input); err != nil {
		return nil, fmt.Errorf("jq: unmarshal input: %w", err)
	}

	iter := code.Run(input)
	v, ok := iter.Next()
	if !ok {
		return nil, nil
	}
	if err, isErr := v.(error); isErr {
		return nil, fmt.Errorf("jq: %w", err)
	}

	result, err := json.Marshal(v)
	if err != nil {
		return nil, fmt.Errorf("jq: marshal result: %w", err)
	}
	return json.RawMessage(result), nil
}

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Inspect the offending event payload and fix the producer to emit valid JSON.
  2. Validate the event body (json.Valid) before applying the jq filter and skip/route invalid events to a dead-letter path.
  3. Check for double encoding: if data looks like "\"{...}\"", unmarshal once more before applying jq.
  4. Verify the pipeline stage upstream of applyJQ isn't truncating or transforming the raw message.

Example fix

// before: jq applied blindly to any payload
out, err := applyJQ(code, data)
// after: validate first
if !json.Valid(data) {
    return fmt.Errorf("event payload is not valid JSON: %q", truncate(data))
}
out, err := applyJQ(code, data)
Defensive patterns

Strategy: validation

Validate before calling

func ensureJSON(data json.RawMessage) error {
    if len(bytes.TrimSpace(data)) == 0 {
        return errors.New("empty payload")
    }
    if !json.Valid(data) {
        return fmt.Errorf("invalid JSON: %s", truncate(data, 200))
    }
    return nil
}

Try / catch

out, err := applyJQ(code, data)
if err != nil {
    var uerr error
    if strings.Contains(err.Error(), "jq: unmarshal input") {
        deadLetter(event, err) // payload not JSON; skip filter
        return nil
    }
    return err
}

Prevention

When it happens

Trigger: json.Unmarshal(data, &input) fails inside applyJQ (internal/event/consume/jq.go:31-35): the event payload passed from processAndOutput is empty, truncated, non-JSON (e.g. plain text or binary), or contains a JSON syntax error such as trailing commas or single quotes.

Common situations: Upstream producer emitted a malformed or empty payload; a preceding pipeline stage corrupted or double-encoded the event; the jq filter was pointed at an event type whose body is not JSON; encoding mismatches (UTF-16/BOM bytes) from a non-Go producer.

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/b0afa661729796ae. Report an issue: GitHub.