Skip to content

Bug: --rule-filter-headers stores JSON as escaped string instead of parsing it #192

@leggetter

Description

@leggetter

Description

When using --rule-filter-headers with JSON format, the CLI stores the headers value as an escaped JSON string instead of parsing it as a JSON object. This results in double-escaping and makes the filter rule difficult to read and potentially incorrect.

IMPORTANT NOTE: Other flags that take JSON may have the same behavior.

Expected Behavior

When passing JSON to --rule-filter-headers, the CLI should parse the JSON and store it as a proper JSON object in the connection rules, matching the behavior when using the --rules flag with a properly structured rules array.

Actual Behavior

The headers value is stored as a stringified/escaped JSON string when using --rule-filter-headers, requiring manual unescaping to read the actual filter criteria.

Steps to Reproduce

Method 1: Using --rule-filter-headers flag (demonstrates the bug)

hookdeck connection upsert test-connection \
  --source-name test-source \
  --source-type WEBHOOK \
  --destination-name test-dest \
  --destination-type HTTP \
  --destination-url https://example.com/webhook \
  --rule-filter-headers '{"x-shopify-topic":{"$startsWith":"order/"}}' \
  --output json > output.json

Check the generated connection rules:

cat output.json | jq '.rules'

Observed output (incorrect):

[
  {
    "type": "filter",
    "headers": "{\"x-shopify-topic\":{\"$startsWith\":\"order/\"}}"
  }
]

Method 2: Using --rules flag (works correctly)

RULES_JSON='[{"type":"filter","headers":{"x-shopify-topic":{"$startsWith":"order/"}}}]'

hookdeck connection upsert test-connection \
  --source-name test-source \
  --source-type WEBHOOK \
  --destination-name test-dest \
  --destination-type HTTP \
  --destination-url https://example.com/webhook \
  --rules "$RULES_JSON" \
  --output json > output.json

Check the generated connection rules:

cat output.json | jq '.rules'

Observed output (correct):

[
  {
    "type": "filter",
    "headers": {
      "x-shopify-topic": {
        "$startsWith": "order/"
      }
    }
  }
]

Expected Output

Both methods should produce the same result - headers stored as a JSON object:

[
  {
    "type": "filter",
    "headers": {
      "x-shopify-topic": {
        "$startsWith": "order/"
      }
    }
  }
]

Workaround

Use the --rules flag with a full rules array instead of individual rule flags:

RULES_JSON='[{"type":"filter","headers":{"x-shopify-topic":{"$startsWith":"order/"}}}]'

hookdeck connection upsert test-connection \
  --source-name test-source \
  --source-type WEBHOOK \
  --destination-name test-dest \
  --destination-type HTTP \
  --destination-url https://example.com/webhook \
  --rules "$RULES_JSON" \
  --output json

Impact

This issue makes it difficult to:

  • Read and verify filter rules in the connection output
  • Understand what filters are actually applied
  • Use the convenient --rule-filter-headers flag for header-based filtering
  • Potentially causes issues with filter rule evaluation (needs verification)

Environment

  • Hookdeck CLI version: [run hookdeck version to get your version]
  • OS: [your OS]
  • Shell: [your shell]

Additional Context

The --rule-filter-headers flag documentation mentions it accepts a "JQ expression", but when using JSON format (as shown in examples), the escaping behavior is unexpected. The --rules flag correctly handles JSON objects, suggesting this is a parsing issue specific to the --rule-filter-headers flag implementation.

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions