Skip to content

Bug: stderr output is mixed into stdout JSON response of @distube/yt-dlp #17

@Thanasis09

Description

@Thanasis09

@distube/yt-dlp currently appends both stdout and stderr into the same output buffer before calling JSON.parse().

This breaks when yt-dlp emits warnings or deprecation notices to stderr, even if the actual JSON response on stdout is valid.

For example, the newer versions of yt-dlp emit

Deprecated Feature: The following options have been deprecated: --no-call-home

yt-dlp writes these messages to stderr even when the process exits successfully with code 0.

Because the wrapper merges stderr into the JSON output buffer, the final string becomes invalid JSON and throws

SyntaxError: Unexpected token 'D', "Deprecated"... is not valid JSON

Current implementation

process2.stdout?.on("data", (chunk) => { 
  output += chunk; 
}); 

process2.stderr?.on("data", (chunk) => { 
  output += chunk; 
});

Suggested fix

Store stderr separately and only parse stdout as JSON output.

let output = ""; 
let errorOutput = ""; 
process2.stdout?.on("data", (chunk) => { 
  output += chunk; 
}); 
process2.stderr?.on("data", (chunk) => { 
  errorOutput += chunk; 
}); 
process2.on("close", (code) => { 
  if (code === 0) resolve(JSON.parse(output)); 
  else reject(new Error(errorOutput || output)); 
});

Environment

  • Node.js v22.22.3
  • Package @distube/yt-dlp
  • OS Debian Linux

I verified that separating stderr from stdout resolves the issue locally.

Diff

This is the diff generated through patch-package;

@distube+yt-dlp+2.0.1.patch

diff --git a/node_modules/@distube/yt-dlp/dist/index.js b/node_modules/@distube/yt-dlp/dist/index.js
index b17b126..ad47539 100644
--- a/node_modules/@distube/yt-dlp/dist/index.js
+++ b/node_modules/@distube/yt-dlp/dist/index.js
@@ -74,15 +74,16 @@ var json = /* @__PURE__ */ __name((url, flags, options) => {
   const process2 = (0, import_node_child_process.spawn)(YTDLP_PATH, args(url, flags), options);
   return new Promise((resolve, reject) => {
     let output = "";
+    let errorOutput = "";
     process2.stdout?.on("data", (chunk) => {
       output += chunk;
     });
     process2.stderr?.on("data", (chunk) => {
-      output += chunk;
+      errorOutput += chunk;
     });
     process2.on("close", (code) => {
       if (code === 0) resolve(JSON.parse(output));
-      else reject(new Error(output));
+      else reject(new Error(errorOutput || output));
     });
     process2.on("error", reject);
   });

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions