{"record":{"id":"b0483518e1c7ed95","repo":"JanDeDobbeleer/oh-my-posh","slug":"received-empty-token-b04835","errorCode":null,"errorMessage":"received empty token","messagePattern":"received empty token","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/auth/tui/ytmda.go","lineNumber":61,"sourceCode":"\tif err != nil {\n\t\ty.err = err\n\t\tsetState(done)\n\t\treturn\n\t}\n\n\ty.code = code\n\tsetState(token)\n\ty.lastState = token\n\n\ttoken, err := y.requestToken(code)\n\tif err != nil {\n\t\ty.err = err\n\t\tsetState(done)\n\t\treturn\n\t}\n\n\tif token == \"\" {\n\t\ty.err = fmt.Errorf(\"received empty token\")\n\t\tsetState(done)\n\t\treturn\n\t}\n\n\tcache.Device.Set(auth.YTMDATOKEN, token, cache.INFINITE)\n\n\tsetState(done)\n}\n\nfunc (y *Ytmda) requestCode() (string, error) {\n\tbody := fmt.Sprintf(`{\"appId\": \"ohmyposh\", \"appName\": \"oh-my-posh\", \"appVersion\": \"%s\"}`, strings.TrimPrefix(build.Version, \"v\"))\n\n\ttype codeResponse struct {\n\t\tCode string `json:\"code\"`\n\t}\n\n\tresult, err := ytmdaRequest[codeResponse](httplib.MethodPost, codeURL, body, y.env)\n","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/JanDeDobbeleer/oh-my-posh/blob/0976794618c5ed95de0985dded50de1b4dc914cb/src/cli/auth/tui/ytmda.go#L43-L79","documentation":"Ytmda.Authenticate authenticates against the YouTube Music Desktop App Companion API: it requests a code, exchanges it for a token, and stores the token. If requestToken returns no error but the token is an empty string (the server replied 200 with a body whose \"token\" field is absent/empty), the flow fails with \"received empty token\" rather than caching a useless empty credential.","triggerScenarios":"POST to /auth/request succeeds at HTTP level and JSON decodes, but the response JSON lacks a non-empty \"token\" field — e.g. the user has not yet pressed Allow, or the Companion API returns an empty/odd body that still unmarshals cleanly.","commonSituations":"The YTMDA Companion API is running but the pop-up approval was never confirmed or already expired; an older YTMDA version returns a differently-shaped JSON body; a proxy strips the token field; the request happened before the user clicked Allow.","solutions":["Retry authentication and make sure to press Allow in the YTMDA pop-up window before the flow completes","Verify the YouTube Music Desktop App is up to date so the Companion API returns a proper token payload","Check Companion API settings in YTMDA (enable companion authorization) and restart the app","Retry after the API recovers; the error is transient server behavior, not a client bug"],"exampleFix":"// before (server returns empty token)\nerr: received empty token\n\n// after (user retries with approval)\n// press Allow in YTMDA, then rerun the authenticate flow","handlingStrategy":"retry","validationCode":null,"typeGuard":"func isEmptyToken(token string) bool { return token == \"\" }","tryCatchPattern":"token, err := requestToken(code)\nif err != nil {\n\treturn err\n}\nif token == \"\" {\n\t// wait for the user to press Allow, then retry once\n\ttime.Sleep(2 * time.Second)\n\ttoken, err = requestToken(code)\n}","preventionTips":["Press Allow in the YTMDA pop-up promptly during the exchange","Keep YouTube Music Desktop App updated so the Companion API returns complete payloads","Enable companion authorization in YTMDA settings before authenticating","Treat empty-token responses as 'not yet approved' and retry after a short delay"],"tags":["authentication","empty-response","api","network","ytmda"],"backgroundTag":"empty-auth-token-response","analyzedSha":"0976794618c5ed95de0985dded50de1b4dc914cb","analyzedAt":"2026-08-31T23:41:19.708Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}