{"record":{"id":"bbeee937f255e262","repo":"iawia002/lux","slug":"404-music-not-found","errorCode":null,"errorMessage":"404 music not found","messagePattern":"404 music not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"extractors/netease/netease.go","lineNumber":38,"sourceCode":"// New returns a netease extractor.\nfunc New() extractors.Extractor {\n\treturn &extractor{}\n}\n\n// Extract is the main function to extract the data.\nfunc (e *extractor) Extract(url string, option extractors.Options) ([]*extractors.Data, error) {\n\turl = strings.Replace(url, \"/#/\", \"/\", 1)\n\tvid := utils.MatchOneOf(url, `/(mv|video)\\?id=(\\w+)`)\n\tif vid == nil {\n\t\treturn nil, errors.New(\"invalid url for netease music\")\n\t}\n\n\thtml, err := request.Get(url, url, nil)\n\tif err != nil {\n\t\treturn nil, errors.WithStack(err)\n\t}\n\tif strings.Contains(html, \"u-errlg-404\") {\n\t\treturn nil, errors.New(\"404 music not found\")\n\t}\n\n\ttitles := utils.MatchOneOf(html, `<meta property=\"og:title\" content=\"(.+?)\" />`)\n\tif titles == nil || len(titles) < 2 {\n\t\treturn nil, errors.WithStack(extractors.ErrURLParseFailed)\n\t}\n\ttitle := titles[1]\n\n\trealURLs := utils.MatchOneOf(html, `<meta property=\"og:video\" content=\"(.+?)\" />`)\n\tif realURLs == nil || len(realURLs) < 2 {\n\t\treturn nil, errors.WithStack(extractors.ErrURLParseFailed)\n\t}\n\trealURL, _ := netURL.QueryUnescape(realURLs[1])\n\n\tsize, err := request.Size(realURL, url)\n\tif err != nil {\n\t\treturn nil, errors.WithStack(err)\n\t}","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/iawia002/lux/blob/dd00f6d258d80b6684a0b9402d7124e5c18ef42f/extractors/netease/netease.go#L20-L56","documentation":"Thrown by the NetEase extractor after it successfully downloads the page HTML for a music.163.com /mv?id=... or /video?id=... URL. If the HTML contains the marker 'u-errlg-404' (the element NetEase renders on its 404 page), the item is considered missing and this error is returned. It means the HTTP request itself worked, but NetEase's own page says the content does not exist.","triggerScenarios":"Calling Extract with a URL whose id parameter refers to a deleted or removed MV (e.g. https://music.163.com/?#/mv?id=XXX where XXX no longer exists), or an id typo'd so the page renders the 404 layout. The URL passed the initial /(mv|video)\\?id=(\\w+) shape check, but the fetched HTML contains 'u-errlg-404'.","commonSituations":"MV taken down for copyright reasons, region-locked MV serving the 404 layout to foreign IPs, or a mistyped/garbled id in a script-generated URL list. Batch jobs scraping playlists hit this on dead links.","solutions":["Open the same URL in a browser and confirm the MV actually exists; if it 404s there too, remove the URL from your input","Verify the id captured by the /(mv|video)\\?id=(\\w+) regex matches the intended MV (print it before calling Extract)","If the video exists but is region-locked, retry from an appropriate network or accept it as unavailable","In batch downloaders, catch this specific message and skip the URL instead of aborting the run"],"exampleFix":"// before\n_, err := extractor.Extract(deadNeteaseURL, opts)\nif err != nil { return err } // aborts whole batch\n\n// after\n_, err := extractor.Extract(neteaseURL, opts)\nif err != nil && strings.Contains(err.Error(), \"404 music not found\") {\n    log.Printf(\"skipping dead track %s\", neteaseURL)\n    continue\n}","handlingStrategy":"try-catch","validationCode":"var neteaseIDRe = regexp.MustCompile(`/(mv|video)\\?id=\\w+`)\n\nfunc isNeteaseCandidateURL(raw string) bool {\n    return neteaseIDRe.MatchString(strings.Replace(raw, \"/#/\", \"/\", 1))\n}","typeGuard":null,"tryCatchPattern":"_, err := netease.Extract(url, opts)\nif err != nil {\n    if strings.Contains(err.Error(), \"404 music not found\") {\n        // content gone; skip, do not retry\n    }\n    if strings.Contains(err.Error(), \"invalid url for netease music\") {\n        // fix the URL shape\n    }\n    return err\n}","preventionTips":["Validate the /(mv|video)?id=... shape before calling Extract","Pre-check URLs with a HEAD request or keep a dead-link cache in batch jobs","Normalize /#/ fragment URLs to path form before extraction"],"tags":["netease","not-found","html-parsing","invalid-url"],"backgroundTag":null,"analyzedSha":"dd00f6d258d80b6684a0b9402d7124e5c18ef42f","analyzedAt":"2026-08-15T16:57:31.080Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}