{"record":{"id":"c9a67454ded749ad","repo":"iawia002/lux","slug":"invalid-url-for-netease-music","errorCode":null,"errorMessage":"invalid url for netease music","messagePattern":"invalid url for netease music","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"extractors/netease/netease.go","lineNumber":30,"sourceCode":")\n\nfunc init() {\n\textractors.Register(\"163\", New())\n}\n\ntype extractor struct{}\n\n// 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 {","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/iawia002/lux/blob/dd00f6d258d80b6684a0b9402d7124e5c18ef42f/extractors/netease/netease.go#L12-L48","documentation":"The netease extractor handles only music.163.com video/mv pages. It first rewrites the hash-route form /#/ to /, then requires /(mv|video)?id=<\\w+>. Any URL without an mv or video id — songs, playlists, albums, artist pages — is rejected before any request is made.","triggerScenarios":"Passing a song page (?id= under /song), playlist, album or artist URL; any link whose id segment does not match \\w+.","commonSituations":"Assuming audio/song downloads are supported; copying links from the netease web player's song pages.","solutions":["Use the MV/video page URL: https://music.163.com/#/mv?id=<id> or https://music.163.com/#/video?id=<id>.","For plain songs, use a tool that supports netease audio; this extractor is video/mv only."],"exampleFix":"// before\n$ lux \"https://music.163.com/#/song?id=186016\"\n// after\n$ lux \"https://music.163.com/#/mv?id=5436392\"","handlingStrategy":"validation","validationCode":"u := strings.Replace(url, \"/#/\", \"/\", 1)\nif utils.MatchOneOf(u, `/(mv|video)\\?id=(\\w+)`) == nil {\n\treturn fmt.Errorf(\"not a netease mv/video URL (song/playlist/album links unsupported): %s\", url)\n}","typeGuard":"func isNeteaseVideoURL(url string) bool {\n\tu := strings.Replace(url, \"/#/\", \"/\", 1)\n\treturn utils.MatchOneOf(u, `/(mv|video)\\?id=(\\w+)`) != nil\n}","tryCatchPattern":null,"preventionTips":["Filter netease inputs to mv/video page URLs only","Route song links to an audio-capable tool instead","Remember the extractor normalizes /#/ hash routes — compare against the normalized form"],"tags":["netease","url-validation","music"],"backgroundTag":null,"analyzedSha":"dd00f6d258d80b6684a0b9402d7124e5c18ef42f","analyzedAt":"2026-08-15T16:57:31.080Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}