{"record":{"id":"05333d42011db35f","repo":"vitest-dev/vitest","slug":"locator-filter-expects-at-least-one-filter-none-p","errorCode":null,"errorMessage":"Locator.filter expects at least one filter. None provided.","messagePattern":"Locator\\.filter expects at least one filter\\. None provided\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/browser/src/client/tester/locators.ts","lineNumber":298,"sourceCode":"      selectors.push(`internal:has-text=${escapeForTextSelector(filter.hasText, false)}`)\n    }\n\n    if (filter?.hasNotText) {\n      selectors.push(`internal:has-not-text=${escapeForTextSelector(filter.hasNotText, false)}`)\n    }\n\n    if (filter?.has) {\n      const locator = filter.has as Locator\n      selectors.push(`internal:has=${JSON.stringify(locator._pwSelector || locator.selector)}`)\n    }\n\n    if (filter?.hasNot) {\n      const locator = filter.hasNot as Locator\n      selectors.push(`internal:has-not=${JSON.stringify(locator._pwSelector || locator.selector)}`)\n    }\n\n    if (!selectors.length) {\n      throw new Error(`Locator.filter expects at least one filter. None provided.`)\n    }\n\n    return this.locator(selectors.join(' >> '))\n  }\n\n  public and(locator: Locator): Locator {\n    return this.locator(`internal:and=${JSON.stringify(locator._pwSelector || locator.selector)}`)\n  }\n\n  public or(locator: Locator): Locator {\n    return this.locator(`internal:or=${JSON.stringify(locator._pwSelector || locator.selector)}`)\n  }\n\n  public query(): HTMLElement | SVGElement | null {\n    const parsedSelector = this._parsedSelector || (this._parsedSelector = selectorEngine.parseSelector(this._pwSelector || this.selector))\n    return selectorEngine.querySelector(parsedSelector, document.documentElement, true) as HTMLElement | SVGElement\n  }\n","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/vitest-dev/vitest/blob/1fa9837ec26533512fdcad8baebf249771bd340a/packages/browser/src/client/tester/locators.ts#L280-L316","documentation":"Thrown by `Locator.prototype.filter` when the `filter` argument contains none of the recognized keys (`hasText`, `hasNotText`, `has`, `hasNot`). The method builds a compound Playwright-style internal selector by pushing one sub-selector per recognized key; if the array stays empty it cannot produce a meaningful locator, so it errors rather than returning an unchanged locator (which would silently ignore the call).","triggerScenarios":"Calling `locator.filter({})`, `locator.filter()` (undefined → no keys), or passing an object with only unrecognized keys (e.g. `{ level: 2 }`).","commonSituations":"Misspelling a filter key (`hasText` → `hastext`); passing a predicate function instead of the expected object shape; passing an empty object as a placeholder; refactoring that drops all filter conditions.","solutions":["Supply at least one recognized key: `locator.filter({ hasText: 'Save' })`, `hasNotText`, `has` (a nested Locator), or `hasNot`.","Check the spelling and capitalization of keys (camelCase, `hasText` not `has_text`).","If no filtering is actually needed, drop the `.filter(...)` call entirely."],"exampleFix":"// before\nlocator.filter({})\n\n// after\nlocator.filter({ hasText: 'Save' })","handlingStrategy":"validation","validationCode":"const recognized = ['hasText', 'hasNotText', 'has', 'hasNot'] as const\nfunction hasRecognizedFilter(f: Record<string, unknown>): boolean {\n  return recognized.some(k => k in f && f[k] != null)\n}\nif (!hasRecognizedFilter(filterObj)) {\n  throw new Error('Provide at least one of hasText, hasNotText, has, hasNot')\n}\nlocator.filter(filterObj)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass at least one of `hasText`, `hasNotText`, `has`, `hasNot`.","Use camelCase keys; double-check spelling.","Drop `.filter()` entirely when no filtering is needed."],"tags":["locator","argument-validation","browser","filter"],"backgroundTag":null,"analyzedSha":"1fa9837ec26533512fdcad8baebf249771bd340a","analyzedAt":"2026-08-11T16:11:39.638Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}