Skip to content

stdlib: URLSearchParams.toString() returns "[object Object]" for every input shape #575

Closed

Description

@proggeramlug

Repro

console.log(JSON.stringify(new URLSearchParams({}).toString()));
console.log(JSON.stringify(new URLSearchParams({ a: "1", b: "2" }).toString()));
console.log(JSON.stringify(new URLSearchParams("a=1").toString()));

bun main.ts:

""
"a=1&b=2"
"a=1"

perry main.ts:

"[object Object]"
"[object Object]"
"[object Object]"

Every input shape — empty record, populated record, query string — produces "[object Object]" from .toString(). Looks like .toString() is falling through to Object.prototype.toString.

Note: per #561 / the related fetch.rs work, URLSearchParams.set(k, v) and .get(k) work in isolation. The bug is specifically .toString() (and likely the constructor's input parsing — even strings come back as "[object Object]").

Why this matters

Discovered while running @bradenmacdonald/s3-lite-client post #572/#573/#574 fix (#551). The package's buildRequestOptions does:

const queryAsString = typeof options.query === "object"
  ? new URLSearchParams(options.query).toString().replace("+", "%20")
  : options.query;

In a presigned-URL flow, queryAsString becomes "[object Object]" — which then gets injected verbatim into the URL path before AWS SigV4 canonicalization. The resulting presigned URL has a stray query parameter ?[object Object]=&... (visible in the issue's repro).

Beyond s3-lite, URLSearchParams is used by every HTTP client / form-encoder / redirect-URL builder in the JS ecosystem.

Acceptance

The repro at the top prints "" / "a=1&b=2" / "a=1" matching bun. Plus regressions:

  • Iterating: for (const [k, v] of params) yields the entries
  • params.has(k), params.delete(k), params.append(k, v) all working against the parsed form
  • URLSearchParams(URLSearchParams) copy-construct
  • Special chars: URLSearchParams({ a: "x y" }).toString() → "a=x+y" (+ for space, not %20)

Refs #551

Activity

  1. added a commit that references this issue on May 8, 2026
    71b51f2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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