Tencent/WeKnora · error

app_secret is required

Error message

app_secret is required

What it means

SaveCredentials (WeKnoraCloud) rejects an empty appSecret. Only the credential presence check — APPID and APPSECRET are both mandatory before the credentials are stored or verified against the cloud health endpoint.

Solutions

  1. Supply the APPSECRET from the WeKnoraCloud console
  2. Check the form/handler didn't drop the secret field
  3. Return a client-side validation error before calling SaveCredentials

Example fix

// before
secret := os.Getenv("WEKNORA_APP_SECRET") // unset -> ""
svc.SaveCredentials(ctx, appID, secret)
// after
secret := os.Getenv("WEKNORA_APP_SECRET")
if secret == "" { return errors.New("WEKNORA_APP_SECRET is not configured") }
svc.SaveCredentials(ctx, appID, secret)
Defensive patterns

Strategy: validation

Validate before calling

if strings.TrimSpace(appSecret) == "" {
	return errors.New("app_secret must be provided before saving credentials")
}

Try / catch

if err := svc.SaveCredentials(ctx, appID, appSecret); err != nil {
	if strings.Contains(err.Error(), "app_secret is required") {
		return fieldError("app_secret", err)
	}
	return err
}

Prevention

When it happens

Trigger: Calling SaveCredentials(ctx, validAppID, "") — blank secret field in the settings form, or unbound/typo'd JSON field so the secret deserializes empty.

Common situations: Secrets manager returns empty during startup and the value is passed through unchecked; user pastes only the APPID; secret trimming removes a whitespace-only value; partial credential update flows that intentionally omit the secret.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at internal/application/service/weknoracloud.go:42

	repo interfaces.ModelRepository,
	tenantRepo interfaces.TenantRepository,
) interfaces.WeKnoraCloudService {
	return &weKnoraCloudService{
		tenantRepo: tenantRepo,
	}
}

func IsWeKnoraCloudDocReaderAddr(addr string) bool {
	return strings.TrimSuffix(strings.TrimSpace(addr), "/") == strings.TrimRight(provider.WeKnoraCloudBaseURL, "/")+"/api/v1/doc/reader"
}

// SaveCredentials 仅保存 APPID/APPSECRET 凭证,不自动创建模型
func (s *weKnoraCloudService) SaveCredentials(ctx context.Context, appID, appSecret string) error {
	if appID == "" {
		return fmt.Errorf("app_id is required")
	}
	if appSecret == "" {
		return fmt.Errorf("app_secret is required")
	}

	if err := s.verifyCredentials(ctx, appID, appSecret); err != nil {
		return fmt.Errorf("credential verification failed: %w", err)
	}

	tenantID := types.MustTenantIDFromContext(ctx)
	return s.updateTenantCredentials(ctx, tenantID, appID, appSecret)
}

// verifyCredentials 向 WeKnoraCloud /api/v1/health 发送带签名头的 GET。
//
// 注意:health 一般为探活接口,远端常不校验 APPID/SECRET 或签名;HTTP 200 通常只表示
// 「网关/服务可达」,不能严格证明凭证有效。若需强校验,应改为调用必须鉴权的业务接口。
func (s *weKnoraCloudService) verifyCredentials(ctx context.Context, appID, appSecret string) error {
	baseURL := strings.TrimRight(provider.WeKnoraCloudBaseURL, "/")
	healthURL := baseURL + "/api/v1/health"

View on GitHub (pinned to 988cbb0330)