{"record":{"id":"89a88aa5d146b034","repo":"wtfutil/wtf","slug":"yfinance-api-error-for-symbol-q-v","errorCode":null,"errorMessage":"yfinance: API error for symbol %q: %v","messagePattern":"yfinance: API error for symbol %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/stocks/yfinance/yquote.go","lineNumber":88,"sourceCode":"\treq.Header.Set(\"User-Agent\", \"Mozilla/5.0 (compatible; wtf-yfinance/1.0)\")\n\n\tresp, err := httpClient.Do(req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"yfinance: unexpected status %d for symbol %q\", resp.StatusCode, symbol)\n\t}\n\n\tvar parsed chartResponse\n\tif err := json.NewDecoder(resp.Body).Decode(&parsed); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif parsed.Chart.Error != nil {\n\t\treturn nil, fmt.Errorf(\"yfinance: API error for symbol %q: %v\", symbol, parsed.Chart.Error)\n\t}\n\n\tif len(parsed.Chart.Result) == 0 {\n\t\treturn nil, fmt.Errorf(\"yfinance: no results for symbol %q\", symbol)\n\t}\n\n\treturn &parsed.Chart.Result[0].Meta, nil\n}\n\n// marketState determines whether the quote is trading pre-market, in the\n// regular session, post-market, or closed, based on the trading period\n// windows Yahoo reports for the current day.\nfunc marketState(periods tradingPeriods) string {\n\tnow := time.Now().Unix()\n\n\tswitch {\n\tcase now < periods.Pre.Start:\n\t\treturn \"CLOSED\"","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/wtfutil/wtf/blob/bb838c1ccb0f0f3223690df44afdec663d622881/modules/stocks/yfinance/yquote.go#L70-L106","documentation":"Yahoo Finance chart responses wrap application-level errors in a chart.error JSON object even when the HTTP status is 200. fetchChartMeta surfaces that nested error (as %v of the parsed error struct) with the symbol for context.","triggerScenarios":"HTTP 200 response whose JSON body contains chart.error non-null — typically \"Invalid input - symbol=xxx\" for malformed or unknown symbols, or Yahoo-side errors returned in-band.","commonSituations":"Typo'd ticker symbols in widget config; symbols with special characters not URL-escaped; Yahoo flagging exchange/symbol combinations as invalid; expired/changed symbol listings.","solutions":["Read the wrapped %v message — it names the actual Yahoo-side problem","Validate the symbol against Yahoo Finance's website search","Fix symbol formatting in config (e.g. use the exact Yahoo notation like BRK-B, ^GSPC)","Add retry/backoff if the message indicates a transient Yahoo error"],"exampleFix":"// before\nclient.GetQuote(\"INVALID SYMBOL WITH SPACES\")\n// after\nclient.GetQuote(\"AAPL\")","handlingStrategy":"validation","validationCode":"valid, _ := regexp.MatchString(`^[A-Za-z0-9^.\\-=]+$`, symbol)\nif !valid || symbol == \"\" { return errors.New(\"invalid symbol format\") }","typeGuard":"func hasChartError(cr chartResponse) bool { return cr.Chart.Error != nil }","tryCatchPattern":"meta, err := fetchChartMeta(symbol)\nif err != nil && strings.HasPrefix(err.Error(), \"yfinance: API error\") {\n    log.Printf(\"Yahoo rejected symbol %q: %v\", symbol, err)\n}","preventionTips":["Use exact Yahoo Finance symbol notation (BRK-B, ^GSPC) in config","URL-escape symbols before building the request URL","Check chart.error before dereferencing chart.result","Test each configured symbol once at startup and log failures early"],"tags":["http","api-error","yfinance","go"],"backgroundTag":"api-error-in-200-response","analyzedSha":"bb838c1ccb0f0f3223690df44afdec663d622881","analyzedAt":"2026-09-03T17:02:45.030Z","contentChangedAt":"2026-09-03T17:02:45.030Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}