Tencent/WeKnora · error

ErrInvalidCredentials

ErrInvalidCredentials

Error message

%w: api_token is required

What it means

The Yuque connector requires a non-empty, non-whitespace api_token credential. parseYuqueConfig wraps datasource.ErrInvalidCredentials when cfg.APIToken is empty after trimming, so the connector cannot authenticate against the Yuque API.

Source

Thrown at internal/datasource/connector/yuque/types.go:78

// parseYuqueConfig extracts and validates Yuque-specific configuration.
// Uses JSON marshal/unmarshal roundtrip (consistent with Feishu's parseFeishuConfig)
// rather than single-field type assertion, because we have multiple fields with
// optional defaults.
func parseYuqueConfig(config *types.DataSourceConfig) (*Config, error) {
	if config == nil {
		return nil, fmt.Errorf("%w: config is nil", datasource.ErrInvalidConfig)
	}
	credBytes, err := json.Marshal(config.Credentials)
	if err != nil {
		return nil, fmt.Errorf("marshal credentials: %w", err)
	}
	var cfg Config
	if err := json.Unmarshal(credBytes, &cfg); err != nil {
		return nil, fmt.Errorf("parse yuque credentials: %w", err)
	}
	if strings.TrimSpace(cfg.APIToken) == "" {
		return nil, fmt.Errorf("%w: api_token is required", datasource.ErrInvalidCredentials)
	}
	if err := datasource.ValidateConnectorBaseURL(cfg.GetBaseURL()); err != nil {
		return nil, err
	}
	return &cfg, nil
}

// --- Yuque API response types ---

// flexibleStatus accepts either a string ("1") or a number (1) for the doc
// `status` field. Yuque's OpenAPI spec declares `status` as string, but the
// runtime API returns it as an integer, so unmarshaling into a plain string
// fails with "cannot unmarshal number into Go struct field ... of type string".
// Normalizing to the textual form lets existing comparisons (e.g. != "1") keep
// working for both response shapes.
type flexibleStatus string

func (s *flexibleStatus) UnmarshalJSON(b []byte) error {

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Set api_token in the datasource credentials to a valid Yuque personal access token (generate at yuque.com settings > developer tokens).
  2. If using env interpolation, verify the env variable is set and non-empty in the runtime environment.
  3. Re-save the datasource after adding the token so the credentials map is persisted.

Example fix

// before
"credentials": {"api_token": ""}
// after
"credentials": {"api_token": "<yuque-personal-access-token>"}
Defensive patterns

Strategy: validation

Validate before calling

if creds["api_token"] == "" || strings.TrimSpace(creds["api_token"].(string)) == "" {
    return errors.New("yuque api_token must be set before validation")
}

Type guard

func hasAPIToken(cfg *Config) bool {
    return cfg != nil && strings.TrimSpace(cfg.APIToken) != ""
}

Try / catch

if _, err := parseYuqueConfig(config); err != nil {
    if errors.Is(err, datasource.ErrInvalidCredentials) {
        return errors.New("configure a Yuque API token in datasource settings")
    }
    return err
}

Prevention

When it happens

Trigger: Credentials map exists but lacks the api_token key, or api_token is "" / whitespace-only.

Common situations: Datasource saved with placeholder credentials; env var holding the token unset so it interpolates to empty; token field renamed in a config update; fresh install where YUQUE_API_TOKEN was never set.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/2b73f20150b49244. Report an issue: GitHub.