{"record":{"id":"e11dae9c9e0bef6f","repo":"Tencent/WeKnora","slug":"query-is-empty-e11dae","errorCode":null,"errorMessage":"query is empty","messagePattern":"query is empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/infrastructure/web_search/bing.go","lineNumber":81,"sourceCode":"\t\tbaseURL: defaultBingSearchURL, // Hardcoded — not tenant-configurable\n\t\tapiKey:  params.APIKey,\n\t}, nil\n}\n\n// Name returns the provider name\nfunc (p *BingProvider) Name() string {\n\treturn \"bing\"\n}\n\n// Search performs a web search using Bing Search API\nfunc (p *BingProvider) Search(\n\tctx context.Context,\n\tquery string,\n\tmaxResults int,\n\tincludeDate bool,\n) ([]*types.WebSearchResult, error) {\n\tif len(query) == 0 {\n\t\treturn nil, fmt.Errorf(\"query is empty\")\n\t}\n\tlogger.Infof(ctx, \"[WebSearch][Bing] query=%q maxResults=%d url=%s\", query, maxResults, p.baseURL)\n\treq, err := p.buildParams(ctx, query, maxResults, includeDate)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tresults, err := p.doSearch(ctx, req)\n\tif err != nil {\n\t\tlogger.Warnf(ctx, \"[WebSearch][Bing] failed: %v\", err)\n\t\treturn nil, err\n\t}\n\tlogger.Infof(ctx, \"[WebSearch][Bing] returned %d results\", len(results))\n\treturn results, nil\n}\n\nfunc (p *BingProvider) doSearch(ctx context.Context, req *http.Request) ([]*types.WebSearchResult, error) {\n\tresp, err := p.client.Do(req)\n\tif err != nil {","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/infrastructure/web_search/bing.go#L63-L99","documentation":"The Bing web search provider rejects a Search call whose query string is empty (len(query) == 0) at the very start of the method, before any network or configuration work. It is a defensive guard so the provider never issues a meaningless API request. The error is created with fmt.Errorf and carries no wrapping.","triggerScenarios":"Calling bingProvider.Search(ctx, \"\", maxResults, includeDate) with a zero-length query string, or passing a query variable that was never populated by an upstream step (empty user input, failed extraction).","commonSituations":"User submits a blank search box; a pipeline stage strips characters (e.g. trimming punctuation) leaving an empty string; a caller forwards a query field from an unvalidated struct.","solutions":["Validate the query in the caller before invoking Search: if strings.TrimSpace(query) == \"\" { return error/early exit }.","Trace where the query originates (user input, config, upstream function) and fix the producer so it never yields an empty string.","If empty queries are legitimate, return a friendly 'please provide a search term' message to the user instead of calling the provider."],"exampleFix":"// before\nresults, err := provider.Search(ctx, userQuery, 10, false)\n// after\nuserQuery = strings.TrimSpace(userQuery)\nif userQuery == \"\" {\n    return nil, errors.New(\"search term is required\")\n}\nresults, err := provider.Search(ctx, userQuery, 10, false)","handlingStrategy":"validation","validationCode":"if strings.TrimSpace(query) == \"\" {\n    return nil, errors.New(\"search query must not be empty\")\n}\nresults, err := provider.Search(ctx, query, maxResults, includeDate)","typeGuard":"func hasQuery(q string) bool { return strings.TrimSpace(q) != \"\" }","tryCatchPattern":null,"preventionTips":["Always trim and check user-supplied search input before calling any provider.","Centralize query validation in a shared helper used by every search entry point.","Reject empty queries at the API/UI layer so they never reach the provider."],"tags":["validation","input","web-search","go"],"backgroundTag":"empty-query-parameter","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}