iawia002/lux · error

string(data.Error)

Error message

string(data.Error)

What it means

The geekbang extractor POSTs to time.geekbang.org/serv/v1/article; when the API answers code < 0 it re-throws the server's own error field, a json.RawMessage converted with string(). The message you see is whatever GeekBang returned — almost always an authentication or permission problem, not a parser failure.

Source

Thrown at extractors/geekbang/geekbang.go:109

		return nil, errors.WithStack(extractors.ErrURLParseFailed)
	}

	// Get video information
	heanders := map[string]string{"Origin": "https://time.geekbang.org", "Content-Type": "application/json", "Referer": url}
	params := strings.NewReader(fmt.Sprintf(`{"id": %q}`, matches[2]))
	res, err := request.Request(http.MethodPost, "https://time.geekbang.org/serv/v1/article", params, heanders)
	if err != nil {
		return nil, errors.WithStack(err)
	}
	defer res.Body.Close() // nolint

	var data geekData
	if err = json.NewDecoder(res.Body).Decode(&data); err != nil {
		return nil, errors.WithStack(err)
	}

	if data.Code < 0 {
		return nil, errors.New(string(data.Error))
	}

	if data.Data.VideoID == "" && !data.Data.ColumnHadSub {
		return nil, errors.New("请先购买课程,或使用Cookie登录。")
	}

	// Get video license token information
	params = strings.NewReader("{\"source_type\":1,\"aid\":" + matches[2] + ",\"video_id\":\"" + data.Data.VideoID + "\"}")
	res, err = request.Request(http.MethodPost, "https://time.geekbang.org/serv/v3/source_auth/video_play_auth", params, heanders)
	if err != nil {
		return nil, errors.WithStack(err)
	}
	defer res.Body.Close() // nolint

	var playAuth videoPlayAuth
	if err = json.NewDecoder(res.Body).Decode(&playAuth); err != nil {
		return nil, errors.WithStack(err)
	}

View on GitHub (pinned to dd00f6d258)

Solutions

  1. Log in at time.geekbang.org, export the cookie, and run lux -c cookie.txt <article-url> (the -c value may be a file path or the raw string).
  2. Confirm the same article opens in a browser using that session.
  3. If the server message is empty, dump the raw response body to read the code/error fields directly.

Example fix

// before
$ lux "https://time.geekbang.org/column/article/123456"
// after
$ lux -c cookie.txt "https://time.geekbang.org/column/article/123456"
Defensive patterns

Strategy: try-catch

Validate before calling

if strings.TrimSpace(cookie) == "" {
	return errors.New("geekbang requires a logged-in cookie: pass -c <cookie-or-file>")
}

Try / catch

Catch and surface the server-provided message verbatim — it already states the real reason (login, permission, bad id). Map it to a re-auth workflow: re-export the cookie and retry the single URL.

Prevention

When it happens

Trigger: Missing, expired or logged-out Cookie header on the article request; malformed article id from the URL; an account that cannot access the article.

Common situations: Forgetting -c; partially pasted cookies; long-running batches where the session expires mid-run.

Related errors


AI-assisted analysis of iawia002/lux@dd00f6d258 (2026-08-15). Data as JSON: /api/errors/8083786751902b95. Report an issue: GitHub.