diff --git a/.changeset/great-zoos-live.md b/.changeset/great-zoos-live.md
new file mode 100644
index 000000000..6d9286f71
--- /dev/null
+++ b/.changeset/great-zoos-live.md
@@ -0,0 +1,5 @@
+---
+"openapi-fetch": patch
+---
+
+fixed `parseAs` behaviour being different for error responses
diff --git a/.changeset/thirty-singers-join.md b/.changeset/thirty-singers-join.md
new file mode 100644
index 000000000..2270bc54e
--- /dev/null
+++ b/.changeset/thirty-singers-join.md
@@ -0,0 +1,5 @@
+---
+"openapi-fetch": patch
+---
+
+fixed empty responses body causing error `Unexpected end of JSON input`
diff --git a/packages/openapi-fetch/src/index.d.ts b/packages/openapi-fetch/src/index.d.ts
index a7b26a1be..84dea3c6c 100644
--- a/packages/openapi-fetch/src/index.d.ts
+++ b/packages/openapi-fetch/src/index.d.ts
@@ -106,7 +106,7 @@ export type FetchResponse<T extends Record<string | number, any>, Options, Media
     }
   | {
       data?: never;
-      error: ErrorResponse<ResponseObjectMap<T>, Media>;
+      error: ParseAsResponse<ErrorResponse<ResponseObjectMap<T>, Media>, Options>;
       response: Response;
     };
 
diff --git a/packages/openapi-fetch/src/index.js b/packages/openapi-fetch/src/index.js
index 1b8502c6f..04840f191 100644
--- a/packages/openapi-fetch/src/index.js
+++ b/packages/openapi-fetch/src/index.js
@@ -150,28 +150,40 @@ export default function createClient(clientOptions) {
       }
     }
 
-    // handle empty content
-    if (response.status === 204 || response.headers.get("Content-Length") === "0") {
-      return response.ok ? { data: undefined, response } : { error: undefined, response };
+    const resultKey = response.ok ? "data" : "error";
+
+    /**
+     * handle empty content
+     * NOTE: Current browsers don't actually conform to the spec requirement to set the body property to null for responses with no body
+     * @see https://developer.mozilla.org/en-US/docs/Web/API/Response/body
+     */
+    if (response.body === null || response.headers.get("Content-Length") === "0") {
+      return { [resultKey]: undefined, response };
     }
 
-    // parse response (falling back to .text() when necessary)
-    if (response.ok) {
-      // if "stream", skip parsing entirely
-      if (parseAs === "stream") {
-        return { data: response.body, response };
-      }
-      return { data: await response[parseAs](), response };
+    if (parseAs === "stream") {
+      return { [resultKey]: response.body, response };
     }
 
-    // handle errors
-    let error = await response.text();
+    // parse response (falling back to .text() when necessary)
     try {
-      error = JSON.parse(error); // attempt to parse as JSON
+      const fallbackResponseClone = response.clone();
+
+      return { [resultKey]: await fallbackResponseClone[parseAs](), response };
     } catch {
-      // noop
+      // handle errors
+      let data = await response.text();
+      try {
+        data = JSON.parse(data); // attempt to parse as JSON
+      } catch {
+        // Handle empty content
+        if (data === "") {
+          data = undefined;
+        }
+      }
+
+      return { [resultKey]: data, response };
     }
-    return { error, response };
   }
 
   return {
diff --git a/packages/openapi-fetch/test/common/response.test.ts b/packages/openapi-fetch/test/common/response.test.ts
index 7a3aacf39..cb674cc32 100644
--- a/packages/openapi-fetch/test/common/response.test.ts
+++ b/packages/openapi-fetch/test/common/response.test.ts
@@ -123,6 +123,22 @@ describe("response", () => {
         assertType<Error>(error);
       }
     });
+
+    test("fallback on null response", async () => {
+      const client = createObservedClient<paths>({}, async () => new Response(undefined, { status: 200 }));
+
+      const { data, error } = await client.GET("/error-empty-response");
+      expect(data).toBe(undefined);
+      expect(error).toBe(undefined);
+    });
+
+    test("fallback on empty body steam", async () => {
+      const client = createObservedClient<paths>({}, async () => new Response("", { status: 200 }));
+
+      const { data, error } = await client.GET("/error-empty-response");
+      expect(data).toBe(undefined);
+      expect(error).toBe(undefined);
+    });
   });
 
   describe("response object", () => {
@@ -135,7 +151,7 @@ describe("response", () => {
     });
   });
 
-  describe("parseAs", () => {
+  describe("data parseAs", () => {
     const client = createObservedClient<paths>({}, async () => Response.json({}));
 
     test("text", async () => {
@@ -192,4 +208,64 @@ describe("response", () => {
       }
     });
   });
+
+  describe("error parseAs", () => {
+    const client = createObservedClient<paths>({}, async () => Response.json({}, { status: 500 }));
+
+    test("text", async () => {
+      const { data, error } = (await client.GET("/resources", {
+        parseAs: "text",
+      })) satisfies { error?: string };
+      if (data) {
+        throw new Error("parseAs text: error");
+      }
+      expect(error).toBe("{}");
+    });
+
+    test("arrayBuffer", async () => {
+      const { data, error } = (await client.GET("/resources", {
+        parseAs: "arrayBuffer",
+      })) satisfies { error?: ArrayBuffer };
+      if (data) {
+        throw new Error("parseAs arrayBuffer: error");
+      }
+      expect(error.byteLength).toBe("{}".length);
+    });
+
+    test("blob", async () => {
+      const { data, error } = (await client.GET("/resources", {
+        parseAs: "blob",
+      })) satisfies { error?: Blob };
+      if (data) {
+        throw new Error("parseAs blob: error");
+      }
+      expect(error.constructor.name).toBe("Blob");
+    });
+
+    test("stream", async () => {
+      const { error } = (await client.GET("/resources", {
+        parseAs: "stream",
+      })) satisfies { error?: ReadableStream<Uint8Array> | null };
+      if (!error) {
+        throw new Error("parseAs stream: error");
+      }
+
+      expect(error).toBeInstanceOf(ReadableStream);
+      const reader = error.getReader();
+      const result = await reader.read();
+      expect(result.value?.length).toBe(2);
+    });
+
+    test("use the selected content", async () => {
+      const client = createObservedClient<paths, "application/ld+json">({}, async () =>
+        Response.json({ bar: "bar" }, { status: 500 }),
+      );
+      const { error } = await client.GET("/media-multiple", {
+        headers: { Accept: "application/ld+json" },
+      });
+      if (error) {
+        assertType<{ bar: string }>(error);
+      }
+    });
+  });
 });
diff --git a/packages/openapi-fetch/test/common/schemas/common.d.ts b/packages/openapi-fetch/test/common/schemas/common.d.ts
index b684c117e..13e7b96d9 100644
--- a/packages/openapi-fetch/test/common/schemas/common.d.ts
+++ b/packages/openapi-fetch/test/common/schemas/common.d.ts
@@ -190,6 +190,46 @@ export interface paths {
         patch?: never;
         trace?: never;
     };
+    "/error-empty-response": {
+        parameters: {
+            query?: never;
+            header?: never;
+            path?: never;
+            cookie?: never;
+        };
+        get: {
+            parameters: {
+                query?: never;
+                header?: never;
+                path?: never;
+                cookie?: never;
+            };
+            requestBody?: never;
+            responses: {
+                /** @description OK */
+                200: {
+                    headers: {
+                        [name: string]: unknown;
+                    };
+                    content?: never;
+                };
+                /** @description No content */
+                204: {
+                    headers: {
+                        [name: string]: unknown;
+                    };
+                    content?: never;
+                };
+            };
+        };
+        put?: never;
+        post?: never;
+        delete?: never;
+        options?: never;
+        head?: never;
+        patch?: never;
+        trace?: never;
+    };
     "/error-default": {
         parameters: {
             query?: never;
diff --git a/packages/openapi-fetch/test/common/schemas/common.yaml b/packages/openapi-fetch/test/common/schemas/common.yaml
index 72e1ea6e2..7f3876d77 100644
--- a/packages/openapi-fetch/test/common/schemas/common.yaml
+++ b/packages/openapi-fetch/test/common/schemas/common.yaml
@@ -79,6 +79,13 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/Error"
+  /error-empty-response:
+    get:
+      responses:
+        200:
+          description: OK
+        204:
+          description: No content
   /error-default:
     get:
       responses:
diff --git a/packages/openapi-fetch/test/never-response/never-response.test.ts b/packages/openapi-fetch/test/never-response/never-response.test.ts
index 43cdb9a4b..202ddb363 100644
--- a/packages/openapi-fetch/test/never-response/never-response.test.ts
+++ b/packages/openapi-fetch/test/never-response/never-response.test.ts
@@ -140,4 +140,32 @@ describe("GET", () => {
     expect(data).toBeUndefined();
     expect(error).toBe("Unauthorized");
   });
+
+  describe("handles error as", () => {
+    test("text", async () => {
+      const client = createObservedClient<paths>({}, async () => new Response("Unauthorized", { status: 401 }));
+
+      const { data, error } = await client.GET("/posts", { parseAs: "text" });
+
+      expect(data).toBeUndefined();
+      expect(error).toBe("Unauthorized");
+    });
+
+    test("stream", async () => {
+      const client = createObservedClient<paths>({}, async () => new Response("Unauthorized", { status: 401 }));
+
+      const { data, error } = (await client.GET("/posts", { parseAs: "stream" })) satisfies {
+        error?: ReadableStream<Uint8Array> | null;
+      };
+      if (!error) {
+        throw new Error("parseAs stream: error");
+      }
+
+      expect(data).toBeUndefined();
+      expect(error).toBeInstanceOf(ReadableStream);
+      const reader = error.getReader();
+      const result = await reader.read();
+      expect(result.value?.length).toBe(12);
+    });
+  });
 });