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

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions