Skip to content

HTTP tools send optional nil query parameters as empty strings instead of omitting them #1737

@Px8Studio

Description

@Px8Studio

Prerequisites

  • I've searched the current open issues
  • I've updated to the latest version of Toolbox

Toolbox version

latest (main branch)

Environment

  1. OS type and version: Any (affects all platforms)
  2. How are you running Toolbox: Local Docker image

Client

  1. Client: Any HTTP tool (see example below)
  2. Version: N/A
  3. Example: Minimal YAML config and curl example below

Expected Behavior

When invoking an HTTP tool with optional query parameters not specified (or set to null/nil), the generated HTTP request URL should omit those parameters. For example, if both page and pageSize are optional and not provided, the URL should be:

https://api.example.com/endpoint

This matches REST API standards, avoids sending empty query values, and prevents API errors.

Current Behavior

The HTTP tool implementation in internal/tools/http/http.go currently converts nil values for optional query parameters to empty strings and always includes them in the request URL (e.g., ?page=&pageSize=). Strict APIs reject these requests with HTTP 400 Bad Request errors, even though the intention is to omit the optional parameters entirely.

Minimal Example

tools:
  my-http-tool:
    kind: http
    source: my-http-source
    method: GET
    path: /data
    queryParams:
      - name: page
        type: integer
        required: false
      - name: pageSize
        type: integer
        required: false

Invoke with:

curl -X POST http://localhost:5000/api/tool/my-http-tool/invoke \
  -H "Content-Type: application/json" \
  -d '{}'

Resulting URL (buggy):

https://api.example.com/data?page=&pageSize=

API returns: HTTP 400 Bad Request

Steps to reproduce?

  1. Create an HTTP tool with optional query parameters as above
  2. Invoke the tool with {} (no parameters)
  3. Observe the generated request URL and HTTP 400 response from the upstream API

Additional Details

  • Root Cause:
    In internal/tools/http/http.go, the getURL() function (lines 210-229) adds ALL query parameters, converting nil to "" (empty string) and always adding them to the query string.
    for _, p := range queryParams {
        v := paramsMap[p.GetName()]
        if v == nil {
            v = ""
        }
        query.Add(p.GetName(), fmt.Sprintf("%v", v))
    }
  • Impact:
    • APIs that validate query parameter values return HTTP 400 errors
    • Affects any HTTP tool with optional query parameters
    • Breaks integrations with strict APIs (e.g., DNB Statistics API)
    • Violates REST API conventions
  • Proposed Solution:
    Update the loop in getURL() to skip optional query parameters when their value is nil, only adding them if required or provided.
    for _, p := range queryParams {
        v, ok := paramsMap[p.GetName()]
        if !ok {
            if p.GetRequired() {
                return "", fmt.Errorf("required query parameter %q is missing", p.GetName())
            }
            continue
        }
        if v == nil {
            if p.GetRequired() {
                v = ""
            } else {
                continue
            }
        }
        query.Add(p.GetName(), fmt.Sprintf("%v", v))
    }
  • Testing:
    • Test with all-optional parameters omitted (expect HTTP 200 OK from API)
    • Test with some provided and some omitted (no empty query values)
    • Test required parameters (should remain enforced)
  • Docs:
    • No documentation change needed; current docs already state optional params can be omitted

References:


Please prioritize this as it breaks compatibility with many APIs and is a standards violation.

Metadata

Metadata

Assignees

Labels

priority: p1Important issue which blocks shipping the next release. Will be fixed prior to next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

Type

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions