{"record":{"id":"af98aabaad2f8bfb","repo":"Tencent/WeKnora","slug":"invalid-verification-token","errorCode":null,"errorMessage":"invalid verification token","messagePattern":"invalid verification token","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/im/feishu/adapter.go","lineNumber":204,"sourceCode":"\tif err := json.Unmarshal(bodyBytes, &encryptedBody); err == nil && encryptedBody.Encrypt != \"\" {\n\t\tdecrypted, err := a.decrypt(encryptedBody.Encrypt)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"decrypt event for verification: %w\", err)\n\t\t}\n\t\traw = decrypted\n\t} else {\n\t\traw = bodyBytes\n\t}\n\n\tvar eventBody struct {\n\t\tHeader *feishuEventHeader `json:\"header\"`\n\t}\n\tif err := json.Unmarshal(raw, &eventBody); err != nil {\n\t\treturn fmt.Errorf(\"unmarshal event header: %w\", err)\n\t}\n\n\tif eventBody.Header == nil || eventBody.Header.Token != a.verificationToken {\n\t\treturn fmt.Errorf(\"invalid verification token\")\n\t}\n\n\treturn nil\n}\n\n// HandleURLVerification handles the Feishu URL verification challenge.\nfunc (a *Adapter) HandleURLVerification(c *gin.Context) bool {\n\tbodyBytes, err := io.ReadAll(c.Request.Body)\n\tif err != nil {\n\t\treturn false\n\t}\n\tc.Request.Body = io.NopCloser(bytes.NewReader(bodyBytes))\n\n\t// Try to parse as a challenge request\n\tvar body map[string]interface{}\n\n\t// If encrypted, try to decrypt first\n\tvar encryptedBody struct {","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/im/feishu/adapter.go#L186-L222","documentation":"VerifyCallback rejects an incoming Feishu event whose header token does not match the adapter's configured verificationToken. Feishu signs each event/callback with the app's verification token; mismatch means the request did not originate from your Feishu app (or credentials are out of sync).","triggerScenarios":"An HTTP callback arrives and eventBody.Header is nil, or eventBody.Header.Token differs from the verification token given at NewAdapter time.","commonSituations":"Callback registered under a different Feishu app than the credentials configured; verification token rotated in the Feishu developer console but not in config; a non-Feishu client probing the webhook endpoint; forwarding events from the wrong environment (test vs production app).","solutions":["Copy the current Verification Token from the Feishu developer console (App Credentials) into the adapter's verificationToken config","Confirm the callback URL is registered to the same app whose token you configured","Reject non-matching requests with 401/403 and check server logs for probing traffic"],"exampleFix":"// before\nadapter, _ := NewAdapter(ctx, Config{VerificationToken: \"old-token\"})\n// after\nadapter, _ := NewAdapter(ctx, Config{VerificationToken: \"current-token-from-console\"})","handlingStrategy":"try-catch","validationCode":"// verify the configured token matches the app in the Feishu console at startup","typeGuard":null,"tryCatchPattern":"if err := adapter.VerifyCallback(req); err != nil {\n    if strings.Contains(err.Error(), \"invalid verification token\") {\n        http.Error(w, \"unauthorized\", http.StatusUnauthorized)\n        return\n    }\n    http.Error(w, \"bad request\", http.StatusBadRequest)\n}","preventionTips":["Sync the verification token from the Feishu console into config via secret manager","Use separate webhook URLs per environment/app","Return 401 on mismatch and alert on repeated failures"],"tags":["webhook","authentication","feishu","verification-token"],"backgroundTag":"webhook-signature-mismatch","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}