iawia002/lux · error
unable to get video ID
Error message
unable to get video ID
What it means
douyin.Extract resolves v.douyin.com share redirects manually, then requires /video/(\d+) in the resulting URL. This error means the resolved URL has no video path: the link points at something other than a standard video page. The subsequent ErrURLParseFailed check in the same block is effectively dead code — only this earlier branch fires.
Source
Thrown at extractors/douyin/douyin.go:59
if err != nil {
return nil, errors.WithStack(err)
}
c := http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}
resp, err := c.Do(req)
if err != nil {
return nil, errors.WithStack(err)
}
defer resp.Body.Close() // nolint
url = resp.Header.Get("location")
}
itemIds := utils.MatchOneOf(url, `/video/(\d+)`)
if len(itemIds) == 0 {
return nil, errors.New("unable to get video ID")
}
if itemIds == nil || len(itemIds) < 2 {
return nil, errors.WithStack(extractors.ErrURLParseFailed)
}
itemId := itemIds[len(itemIds)-1]
// dynamic generate cookie
cookie, err := createCookie()
if err != nil {
return nil, errors.WithStack(err)
}
api := "https://www.douyin.com/aweme/v1/web/aweme/detail/?aweme_id=" + itemId
// parse api query params string
query, err := netURL.Parse(api)
if err != nil {
return nil, errors.WithStack(extractors.ErrURLQueryParamsParseFailed)
}View on GitHub (pinned to dd00f6d258)
Solutions
- Open the share link in a browser and pass the final www.douyin.com/video/<digits> URL instead.
- For image/note posts this extractor does not apply — use a tool that supports douyin images.
- Log the resolved URL after the redirect loop; if it is still v.douyin.com, the manual redirect following needs another hop.
- If douyin introduced new path shapes, extend the /video/(\d+) pattern.
Example fix
// before itemIds := utils.MatchOneOf(url, `/video/(\d+)`) // after — surface what the redirect produced before failing fmt.Fprintln(os.Stderr, "douyin: resolved to", url) itemIds := utils.MatchOneOf(url, `/(video|note)/(\d+)`)
Defensive patterns
Strategy: validation
Validate before calling
u := strings.TrimSpace(rawURL)
if strings.Contains(u, "v.douyin.com") {
u = resolveShareLink(u) // follow the redirect yourself first
}
if utils.MatchOneOf(u, `/video/(\d+)`) == nil {
return fmt.Errorf("not a douyin video link (resolved to %s)", u)
} Type guard
func isDouyinVideoURL(u string) bool {
return utils.MatchOneOf(u, `/video/(\d+)`) != nil
} Try / catch
If caught, log the resolved URL alongside the error — it shows which non-video page (note/profile/live) the share link actually pointed to, which is the actionable datum.
Prevention
- Expand share links to their final www.douyin.com form before extraction
- Keep image/note posts out of video-extraction pipelines
- Log the post-redirect URL for every douyin job so misrouted links are visible
When it happens
Trigger: Share links that resolve to /note/ (image slideshows), user profiles or live pages; redirect chains where the location header was empty so the URL never gained the /video/ segment; douyin changing path formats.
Common situations: Copying app share text for photo posts; proxies altering or stripping redirects; douyin URL-scheme evolution.
Related errors
- couldn't extract the media short code from the link
- Invalid video URL: Missing video ID parameter
- douyin ttwid request failed
- 暂不支持斗鱼直播
- ErrURLQueryParamsParseFailed
AI-assisted analysis of iawia002/lux@dd00f6d258 (2026-08-15).
Data as JSON: /api/errors/cb7808f3114821fa.
Report an issue: GitHub.