{"record":{"id":"989cd677ba1f2a37","repo":"cube-js/cube","slug":"member-attribute-is-required-for-filter-json-str","errorCode":null,"errorMessage":"member attribute is required for filter ${JSON.stringify(f)}","messagePattern":"member attribute is required for filter (.+?)","errorType":"exception","errorClass":"UserError","httpStatus":null,"severity":"error","filePath":"packages/cubejs-schema-compiler/src/adapter/BaseQuery.js","lineNumber":167,"sourceCode":"    this.orderHashToString = this.orderHashToString.bind(this);\n    this.defaultOrder = this.defaultOrder.bind(this);\n    /** @type {ParamAllocator} */\n    this.paramAllocator = this.options.paramAllocator || this.newParamAllocator(this.options.expressionParams);\n    this.initFromOptions();\n  }\n\n  extractDimensionsAndMeasures(filters = []) {\n    if (!filters) {\n      return [];\n    }\n    let allFilters = [];\n    filters.forEach(f => {\n      if (f.and) {\n        allFilters = allFilters.concat(this.extractDimensionsAndMeasures(f.and));\n      } else if (f.or) {\n        allFilters = allFilters.concat(this.extractDimensionsAndMeasures(f.or));\n      } else if (!f.member && !f.dimension) {\n        throw new UserError(`member attribute is required for filter ${JSON.stringify(f)}`);\n      } else if (this.cubeEvaluator.isMeasure(f.member || f.dimension)) {\n        allFilters.push({ measure: f.member || f.dimension });\n      } else {\n        allFilters.push({ dimension: f.member || f.dimension });\n      }\n    });\n\n    return allFilters;\n  }\n\n  keepFilters(filters = [], fn) {\n    return filters.map(f => {\n      if (f.and) {\n        return { and: this.keepFilters(f.and, fn) };\n      } else if (f.or) {\n        return { or: this.keepFilters(f.or, fn) };\n      } else if (!f.member && !f.dimension) {\n        throw new UserError(`member attribute is required for filter ${JSON.stringify(f)}`);","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-schema-compiler/src/adapter/BaseQuery.js#L149-L185","documentation":"Cube's BaseQuery flattens query filters into dimension/measure references. Every leaf filter object must identify the member it filters via a 'member' (or legacy 'dimension') property; otherwise the query cannot be compiled. The library throws this UserError when a filter has neither property, because it cannot know which cube member the condition applies to.","triggerScenarios":"Passing a filter object to the query 'filters' array that only has operator/values (e.g. {operator:'equals', values:['x']}) or a typo'd key like 'members' or 'field' instead of 'member'. Also triggered by nested and/or groups containing such malformed leaves, via extractDimensionsAndMeasures.","commonSituations":"Hand-written JSON queries in API clients, dynamically generated filters where the member variable is undefined/empty, migrating from other query languages that use 'field', or upgrading Cube where filter keys changed.","solutions":["Add a 'member' property to every leaf filter object","Check for typos: the key must be 'member' (or 'dimension')","Log JSON.stringify(f) from the error message to find the offending filter","If filters are built dynamically, guard that the member value is a non-empty string before pushing"],"exampleFix":"// before\n{ operator: 'equals', values: ['green'] }\n// after\n{ member: 'Products.color', operator: 'equals', values: ['green'] }","handlingStrategy":"validation","validationCode":"function validateFilters(filters) {\n  (filters || []).forEach(f => {\n    if (f.and) return validateFilters(f.and);\n    if (f.or) return validateFilters(f.or);\n    if (!f.member && !f.dimension) {\n      throw new Error(`Filter missing member: ${JSON.stringify(f)}`);\n    }\n  });\n}\nvalidateFilters(query.filters);","typeGuard":"const isFilterLeaf = (f) => typeof f === 'object' && f !== null && (typeof f.member === 'string' || typeof f.dimension === 'string');","tryCatchPattern":"try {\n  await cube.query(query);\n} catch (e) {\n  if (e instanceof UserError && /member attribute is required for filter/.test(e.message)) {\n    console.error('Malformed filter object:', e.message);\n  } else throw e;\n}","preventionTips":["Always use the {member, operator, values} filter shape","Never build filter objects with dynamic keys; validate member is a non-empty string","Add a query builder helper that enforces the shape","Test queries against the compiler in CI before shipping dashboards"],"tags":["query","filters","validation"],"backgroundTag":"missing-filter-member","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}