Skip to content

Bug: URLSearchParams silently corrupts object values to [object Object] #3109

@PlaneInABottle

Description

@PlaneInABottle

Description

When an API block sends a request with Content-Type: application/x-www-form-urlencoded header and the body contains nested objects or arrays, the values are silently corrupted to the literal string [object Object] instead of being properly serialized.

Location

  • File: /apps/sim/tools/http/request.ts
  • Line: 130
  • Code: urlencoded.append(key, String(value))

Root Cause

JavaScript's String() function calls Object.prototype.toString() which returns [object Object] for plain objects. When iterating over body entries and converting values to strings, nested objects and arrays are silently corrupted.

String({nested: "value"})  // Returns "[object Object]"
String([1, 2, 3])         // Returns "1,2,3" (loses array structure)

Reproduction Steps

  1. Create an API block in a workflow
  2. Configure it with:
    • Method: POST
    • Headers: Content-Type: application/x-www-form-urlencoded
    • Body: {data: {nested: "value"}, items: [1, 2, 3]}
  3. Execute the workflow
  4. Inspect the actual HTTP request sent

Expected vs Actual

Expected body:

data=%7B%22nested%22%3A%22value%22%7D&items=%5B1%2C2%2C3%5D
(URL-encoded JSON for nested objects/arrays)

Actual body:

data=%5Bobject%20Object%5D&items=1%2C2%2C3
(Corrupted: [object Object] and array loses structure)

Impact

  • Severity: HIGH - Data Corruption
  • Type: Silent Data Loss
  • Scope: Any API integration using form-urlencoded bodies with nested objects/arrays
  • Silent Failure: No error message, request appears to succeed but data is corrupted

Code Context (lines 116-140)

if (params.body) {
  const parsedHeaders = parseTableData(params.headers)
  const headers = transformTable(parsedHeaders)
  const contentType = headers['Content-Type'] || headers['content-type']

  if (
    contentType === 'application/x-www-form-urlencoded' &&
    typeof params.body === 'object'
  ) {
    // Convert JSON object to URL-encoded string
    const urlencoded = new URLSearchParams()
    Object.entries(params.body as Record<string, unknown>).forEach(([key, value]) => {
      if (value !== undefined && value !== null) {
        urlencoded.append(key, String(value))  // <-- BUG: String(object) = "[object Object]"
      }
    })
    return urlencoded.toString()
  }
  return params.body as Record<string, any>
}

Type Safety Issue

The body type signature is Record<string, unknown> which explicitly allows objects as values. The code needs to handle this case properly rather than silently corrupting the data.

Suggested Fix

Replace line 130:

Before:

urlencoded.append(key, String(value))

After:

urlencoded.append(
  key,
  typeof value === 'object' ? JSON.stringify(value) : String(value)
)

This ensures:

  • Objects are properly JSON serialized
  • Arrays are converted to JSON arrays instead of comma-separated strings
  • Primitive values continue to work as before
  • No data corruption occurs

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions