linsomniac/spotify_to_ytmusic

ERROR: Unable to look up song on YTMusic: Server returned HTTP 400: Bad Request. Request contains an invalid argument.

Opened this issue · 35 comments

When I go to the “Load liked song” step and press the “Load” button, I get the following message for YTMUSIC:
ERROR: Unable to look up song on YTMusic: Server returned HTTP 400: Bad Request.
Request contains an invalid argument.

I tried to upgrade ytmusicapi:
pip install ytmusicapi --upgrade --user
upgrading to version 1.8.2.
I try again the “Load liked song” step and get the same result:
ERROR: Unable to look up song on YTMusic: Server returned HTTP 400: Bad Request.
Request contains an invalid argument.
image

I am also facing this problem, if anybody has a solution it would help a lot. Thanks

Having the same issue as well and cannot for the life of me figure out the fix, i just wanna send my spotify over so i can reduce my subscriptions 😭

This is likely related to an issue in a library that has an open ticket and recent responses by a dev: sigma67/ytmusicapi#676

Getting the same issue but with a twist:

context:

  • I am the master user of a Youtube Premium family account and have my wife and kids as 'family' members.
  • I run the command line version of the app

All commands work fine (listing, importing, etc) when used with my google account, but I get the error (400) when I run the commands via my wife and kids accounts.

Same issue here. I tried using my master account for YouTube Premium family like @jjrossi mentioned and everything worked.

Not a solution to the original problem though

Same problem. "ERROR: Unable to look up song on YTMusic: Server returned HTTP 400: Bad Request.
Request contains an invalid argument."

Same issue here, using command line on linux (windows subsystem for linux, ubuntu). Downloading all the information from spotify works fine, but any request to yt fails with the HTTP 400: Bad Request error.

I have a solution. Search up Tune My Music on google then click "let's start". Proceed with the steps to move your spotify playlist to youtube music. The limit for each transfer is 500 songs, after in which Tune My Music will then ask for a subscription. To bypass this just close the tab and open a new one to repeat the whole process again.

The issue is with google no longer supporting oauth authentication.
Here's what worked for me - following alternative authentication issue by sigma67:

  1. Open a new tab, enter developer mode (ctrl+shift_i), enter 'Network' tab. Filter using the filter textbox by: /browse
  2. Go to https://music.youtube.com/ (while connected to your desired account) and click 'Library' at the sidebar.
  3. In your developer mode inspector you will see a new request under 'Name' which starts with 'browse?', click it, manually select and copy everything under 'Request Headers'.
  4. In terminal, run 'ytmusicapi browser', paste the headers you've just copied, press Enter, press ctrl+D. A new file 'browser.json' should be created in your current dir.
  5. Change in your installed spotify2ytmusic package's source code: above this line in backend.py write 'return YTMusic("browser.json")'.

Following these 5 steps you should be able to use this tool as before.
Hope this helps!

P.S. If you're confused about step 3, here's what you should copy (until the end of 'Request Headers') & how you should (at the very top of the image) filter to find the request:
image

The issue is with google no longer supporting oauth authentication. Here's what worked for me - following alternative authentication issue by sigma67:

  1. Open a new tab, enter developer mode (ctrl+shift_i), enter 'Network' tab. Filter using the filter textbox by: /browse
  2. Go to https://music.youtube.com/ (while connected to your desired account) and click 'Library' at the sidebar.
  3. In your developer mode inspector you will see a new request under 'Name' which starts with 'browse?', click it, manually select and copy everything under 'Request Headers'.
  4. In terminal, run 'ytmusicapi browser', paste the headers you've just copied, press Enter, press ctrl+D. A new file 'browser.json' should be created in your current dir.
  5. Change in your installed spotify2ytmusic package's source code: above [this line in backend.py] write 'return YTMusic("browser.json")'.

Following these 5 steps you should be able to use this tool as before. Hope this helps!

P.S. If you're confused about step 3, here's what you should copy (until the end of 'Request Headers') & how you should (at the very top of the image) filter to find the request: image

"this line" is line 28 in backend.py

27 try:
28  return YTMusic("oauth.json") # change this

update nvm i found it for anyone wanting the path for where to find backend.py this is where i found mine
C:\Program Files\Python313\Lib\site-packages\spotify2ytmusic
good luck and god speed

Hi I seem to be having this same issue and I am attempting this solution, but my ytmusicapi browser command does not appear to work. This is what I am getting, forgive me if I am doing some terribly basic error:

PS C:\Users\Name> py -m ytmusicapi browser
C:\Users\Name\AppData\Local\Programs\Python\Python313\python.exe: No module named ytmusicapi.__main__; 'ytmusicapi' is a package and cannot be directly executed

I also don't see a browse?ctoken= network request, only a prettyprint one (the first one in the image)

The latest pull request on this has the details. You need to change 4 .py files in the package. Details in files here: #132

Dont forget first to do the stuff here to build the browser.json file: #125 (comment)

Hi I seem to be having this same issue and I am attempting this solution, but my ytmusicapi browser command does not appear to work. This is what I am getting, forgive me if I am doing some terribly basic error:

PS C:\Users\Name> py -m ytmusicapi browser
C:\Users\Name\AppData\Local\Programs\Python\Python313\python.exe: No module named ytmusicapi.__main__; 'ytmusicapi' is a package and cannot be directly executed

I also don't see a browse?ctoken= network request, only a prettyprint one (the first one in the image)

I had same issue on Windows. Try using venv.

python -m venv myenv
.\myenv\Scripts\activate.bat
pip install ytmusicapi
ytmusicapi browser

Then continue using @ohadklein11 instructions

I've updated my files to what was in the pull request, but I still can't seem to get to the point where I can build the browser. still running into the problem where it won't let me run ytmusicapi browser. I'm using windows powershell and my PATH is set up to include the python scripts

PS C:\Users\Name> py -m venv myenv
PS C:\Users\Name> .\myenv\Scripts\activate.bat
PS C:\Users\Name> py -m pip install ytmusicapi
Requirement already satisfied: ytmusicapi in c:\users\Name\appdata\local\programs\python\python313\lib\site-packages (1.8.2)
Requirement already satisfied: requests>=2.22 in c:\users\Name\appdata\local\programs\python\python313\lib\site-packages (from ytmusicapi) (2.32.3)
Requirement already satisfied: charset-normalizer<4,>=2 in c:\users\Name\appdata\local\programs\python\python313\lib\site-packages (from requests>=2.22->ytmusicapi) (3.4.0)
Requirement already satisfied: idna<4,>=2.5 in c:\users\Name\appdata\local\programs\python\python313\lib\site-packages (from requests>=2.22->ytmusicapi) (3.10)
Requirement already satisfied: urllib3<3,>=1.21.1 in c:\users\Name\appdata\local\programs\python\python313\lib\site-packages (from requests>=2.22->ytmusicapi) (2.2.3)
Requirement already satisfied: certifi>=2017.4.17 in c:\users\Name\appdata\local\programs\python\python313\lib\site-packages (from requests>=2.22->ytmusicapi) (2024.8.30)

[notice] A new release of pip is available: 24.2 -> 24.3.1
[notice] To update, run: C:\Users\Name\AppData\Local\Programs\Python\Python313\python.exe -m pip install --upgrade pip
PS C:\Users\Name> py -m ytmusicapi browser
C:\Users\Name\AppData\Local\Programs\Python\Python313\python.exe: No module named ytmusicapi.__main__; 'ytmusicapi' is a package and cannot be directly executed

I just straight used cmd, I see ur in Powershell, dunno if mkes a difference, worth a try

Yes use command prompt instead of powershell:

C:\example>python -m venv myenv

C:\example>.\myenv\Scripts\activate.bat

(myenv) C:\example>pip install ytmusicapi
Collecting ytmusicapi
  Using cached ytmusicapi-1.8.2-py3-none-any.whl.metadata (5.5 kB)
Collecting requests>=2.22 (from ytmusicapi)
...

(myenv) C:\example>ytmusicapi browser
Creating browser.json with your authentication credentials...
Please paste the request headers from Firefox and press 'Enter, Ctrl-Z, Enter' to continue:

How am i supposed to get that ctoken browser request every time i try to i can only get pretty print one

Yes use command prompt instead of powershell:

C:\example>python -m venv myenv

C:\example>.\myenv\Scripts\activate.bat

(myenv) C:\example>pip install ytmusicapi
Collecting ytmusicapi
  Using cached ytmusicapi-1.8.2-py3-none-any.whl.metadata (5.5 kB)
Collecting requests>=2.22 (from ytmusicapi)
...

(myenv) C:\example>ytmusicapi browser
Creating browser.json with your authentication credentials...
Please paste the request headers from Firefox and press 'Enter, Ctrl-Z, Enter' to continue:

awesome, I have it working now so far, thanks everybody for the help!

How am i supposed to get that ctoken browser request every time i try to i can only get pretty print one

I used the pretty print one and it worked

Hello everybody. I'm trying to paste all the Request Headers into macOS terminal, but it seems it has a paste limit and will not paste all the headers. Can somebody please tell me how have you managed to paste all the Request Headers into Terminal? Than you in advance and wish you all a great day.

Hello everybody. I'm trying to paste all the Request Headers into macOS terminal, but it seems it has a paste limit and will not paste all the headers. Can somebody please tell me how have you managed to paste all the Request Headers into Terminal? Than you in advance and wish you all a great day.

After you copy the request headers, run pbpaste | ytmusicapi browser instead

Yes use command prompt instead of powershell:

C:\example>python -m venv myenv

C:\example>.\myenv\Scripts\activate.bat

(myenv) C:\example>pip install ytmusicapi
Collecting ytmusicapi
  Using cached ytmusicapi-1.8.2-py3-none-any.whl.metadata (5.5 kB)
Collecting requests>=2.22 (from ytmusicapi)
...

(myenv) C:\example>ytmusicapi browser
Creating browser.json with your authentication credentials...
Please paste the request headers from Firefox and press 'Enter, Ctrl-Z, Enter' to continue:

awesome, I have it working now so far, thanks everybody for the help!

How am i supposed to get that ctoken browser request every time i try to i can only get pretty print one

I used the pretty print one and it worked

I tried the print one and it did not work :( - any ideas??? - no ctoken is generating on youtube music

4. In terminal, run 'ytmusicapi browser', paste the headers you've just copied, press Enter, press ctrl+D. A new file 'browser.json' should be created in your current dir.

It should be mentioned that the request headers expire after 10 minutes so while copying once you see the 401 Request Unauthorized error, you have to reload the headers in a browser and get new ones. You will also need to remove all songs in the playlist.json file that are already done to avoid the headers timing out at the same spot again.

In playlist.json, each song is a list object, the first key of a song object called "added_at".

  1. In terminal, run 'ytmusicapi browser', paste the headers you've just copied, press Enter, press ctrl+D. A new file 'browser.json' should be created in your current dir.

It should be mentioned that the request headers expire after 10 minutes so while copying once you see the 401 Request Unauthorized error, you have to reload the headers in a browser and get new ones. You will also need to remove all songs in the playlist.json file that are already done to avoid the headers timing out at the same spot again.

In playlist.json, each song is a list object, the first key of a song object called "added_at".

how can i remove songs in playlist.json?

also instead of editing the source code you can just rename browser.json to oauth.json

hey all, this is pretty confusing for me. when trying the workaround, all i get is
https://music.youtube.com/youtubei/v1/browse?prettyPrint=false

and no entry with the token. am i doing something wrong? thanks

hey all, this is pretty confusing for me. when trying the workaround, all i get is https://music.youtube.com/youtubei/v1/browse?prettyPrint=false

and no entry with the token. am i doing something wrong? thanks

Copy the request headers under that it worked for me. I also didn't get entry with token

Is there a way to bypass request headers expiring every 10min ?

5. Change in your installed spotify2ytmusic package's source code: above this line in backend.py write 'return YTMusic("browser.json")'.

if you have hard time in doing this 5th step,
below hack worked for me in Mac
Renaming the browser.json file to oauth.json should work fine

I am not sure why this is not recommended,
@ohadklein11 can you pls answer this?

Is there a way to bypass request headers expiring every 10min ?

It's not ideal, but what I ended up doing was adding yt = get_ytmusic() to all excepts in backend.py (example). This allowed me to re-run the steps above to generate a new "browser.json" file that gets picked up on the next retry. It does require you to manually get request headers every 10 minutes, but at least it works?

@udaya28 Your suggestion is a good workaround. I just wanted to be more careful (since you cannot know what other code logics might rely on the existence of the oauth.json file). If everything works then great 👍

Tune My Music

You say you can just close the tab and re-open the tab and continue, but I find it's still trying to force a subscription to continue?

Is there a way to bypass request headers expiring every 10min ?

It's not ideal, but what I ended up doing was adding yt = get_ytmusic() to all excepts in backend.py (example). This allowed me to re-run the steps above to generate a new "browser.json" file that gets picked up on the next retry. It does require you to manually get request headers every 10 minutes, but at least it works?

I did it little bit differently. I edited method responsible for iteration such as it skips all tracks till track defined by me is not found.
Still it needs request header to be regenerated.

for find_spotify_playlist you need to replace code between pl_tracks = reversed(pl_tracks) and yield SongInfo(src_track_name, src_track_artist, src_album_name)

to

 unlock = False
    for src_track in pl_tracks:

        if src_track["track"] is None:
            print(
                f"WARNING: Spotify track seems to be malformed, Skipping.  Track: {src_track!r}"
            )
            continue

        try:
            src_album_name = src_track["track"]["album"]["name"]
            src_track_artist = src_track["track"]["artists"][0]["name"]
        except TypeError as e:
            print(f"ERROR: Spotify track seems to be malformed.  Track: {src_track!r}")
            raise e
        src_track_name = src_track["track"]["name"]
        if  "Epitaph" in src_track_name:
            unlock = True
        if unlock == False:
            print(f"Skipping spotify track:   {src_track_name} - {src_track_artist} - {src_album_name}")
            continue

for this case my last liked track was "Epitaph". You need to change it for your last liked track