{"record":{"id":"6c19d7f6bd72b8fe","repo":"Tencent/WeKnora","slug":"embed-visitor-id-too-long-max-128","errorCode":null,"errorMessage":"embed visitor id too long (max 128)","messagePattern":"embed visitor id too long \\(max 128\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/types/principal.go","lineNumber":132,"sourceCode":"\t}\n}\n\n// EmbedVisitorPrincipal identifies one anonymous embed visitor (browser).\nfunc EmbedVisitorPrincipal(tenantID uint64, channelID, visitorID string) Principal {\n\treturn Principal{\n\t\tType: PrincipalEmbedVisitor,\n\t\tID:   fmt.Sprintf(\"%d:%s:%s\", tenantID, strings.TrimSpace(channelID), strings.TrimSpace(visitorID)),\n\t}\n}\n\n// ValidateEmbedVisitorID checks the client-supplied anonymous visitor id.\nfunc ValidateEmbedVisitorID(id string) error {\n\tid = strings.TrimSpace(id)\n\tif id == \"\" {\n\t\treturn fmt.Errorf(\"empty embed visitor id\")\n\t}\n\tif len(id) > 128 {\n\t\treturn fmt.Errorf(\"embed visitor id too long (max 128)\")\n\t}\n\tfor _, r := range id {\n\t\tif r < 0x20 || r == 0x7f {\n\t\t\treturn fmt.Errorf(\"embed visitor id contains invalid characters\")\n\t\t}\n\t}\n\treturn nil\n}\n\n// MCPOAuthPrincipalFromContext resolves the OAuth token principal for ctx.\n// Embed chat sessions map to a per-visitor principal when X-Embed-Visitor is\n// present; otherwise OAuth falls back to the chat session principal.\nfunc MCPOAuthPrincipalFromContext(ctx context.Context) Principal {\n\tp, ok := PrincipalFromContext(ctx)\n\tif !ok {\n\t\treturn Principal{}\n\t}\n\tp = p.Normalize()","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/types/principal.go#L114-L150","documentation":"Guard error in ValidateEmbedVisitorID: the client-supplied anonymous embed visitor ID is non-empty but longer than 128 bytes, so ensureEmbedSession refuses to build an embed visitor principal from it. The limit bounds the Principal ID string size.","triggerScenarios":"Calling ensureEmbedSession with a visitor id whose length exceeds 128 bytes — e.g. an over-long generated token, concatenated identifiers, or a JWT/prefixed value stuffed into the visitor id field.","commonSituations":"Frontend storing a full session token or telemetry id instead of a short UUID in the visitor id slot; id built by concatenating multiple ids or timestamps; base64 blobs copied from other systems.","solutions":["Issue shorter visitor IDs on the embed client side","Trim or hash overly long client-supplied visitor IDs before validation"],"exampleFix":"// before\nvisitorID := jwtToken // hundreds of bytes\n// after\nvisitorID := uuid.NewString() // 36 chars, well under 128","handlingStrategy":"validation","validationCode":"if len(visitorID) > 128 { visitorID = visitorID[:128] } // or regenerate\nif len(visitorID) == 0 { visitorID = uuid.NewString() }","typeGuard":"func visitorIDLengthOK(id string) bool { return len(id) > 0 && len(id) <= 128 }","tryCatchPattern":"if err := ValidateEmbedVisitorID(id); err != nil {\n    if strings.Contains(err.Error(), \"too long\") {\n        id = uuid.NewString() // replace oversized id\n    }\n}","preventionTips":["Use UUIDs (36 chars) as visitor ids, never tokens or concatenated values","Check byte length (len), not rune count, before sending","Keep token-like credentials out of the visitor id field"],"tags":["validation","embed","session","go"],"backgroundTag":"parameter-too-long","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}