Tencent/WeKnora · error

app_id is required

Error message

app_id is required

What it means

weKnoraCloudService.SaveCredentials stores WeKnora Cloud APPID/APPSECRET credentials for a tenant, but first requires appID to be non-empty. An empty appID is rejected immediately before any network verification happens.

Source

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

// NewWeKnoraCloudService 构造 WeKnoraCloudService
func NewWeKnoraCloudService(
	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 {

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Pass a non-empty appID to SaveCredentials after reading it from the request/config.
  2. Fix the request binding so the client's field name matches the struct's JSON tag (app_id).
  3. Add client-side required-field validation on the APPID input before submit.
  4. Return a 400 with this message from the handler so users see the missing field clearly.

Example fix

// before
svc.SaveCredentials(ctx, r.FormValue("appid"), r.FormValue("app_secret")) // typo -> ""
// after
appID := r.FormValue("app_id")
if appID == "" { http.Error(w, "app_id is required", 400); return }
svc.SaveCredentials(ctx, appID, r.FormValue("app_secret"))
Defensive patterns

Strategy: validation

Validate before calling

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

Try / catch

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

Prevention

When it happens

Trigger: Calling SaveCredentials(ctx, "", secret) — e.g. an API handler that did not bind the app_id field from the request body, or a form where the APPID input was left blank.

Common situations: Frontend sends only the secret after a partial form fill; JSON field name mismatch (appID vs app_id) so the value unmarshals to empty string; config loader omits APPID because it's assumed to live elsewhere.

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/1f019fdab25cf90d. Report an issue: GitHub.