{"record":{"id":"54a8b9b6fa05bc87","repo":"langfuse/langfuse","slug":"invalid-dimension-dimension-field-must-be-one","errorCode":null,"errorMessage":"Invalid dimension ${dimension.field}. Must be one of ${Object.keys(view.dimensions)}","messagePattern":"Invalid dimension (.+?)\\. Must be one of (.+?)","errorType":"exception","errorClass":"InvalidRequestError","httpStatus":400,"severity":"error","filePath":"packages/shared/src/features/query/server/queryBuilder.ts","lineNumber":281,"sourceCode":"      dimension.explodeArray ||\n      dimension.pairExpand ||\n      dimension.aggregationFunction\n    ) {\n      throw new InvalidRequestError(\n        `Invalid entity dimension: ${field}. Entity dimensions must be scalar view dimensions.`,\n      );\n    }\n\n    return dimension;\n  }\n\n  private mapDimensions(\n    dimensions: Array<{ field: string }>,\n    view: ViewDeclarationType,\n  ): AppliedDimensionType[] {\n    return dimensions.map((dimension) => {\n      if (!(dimension.field in view.dimensions)) {\n        throw new InvalidRequestError(\n          `Invalid dimension ${dimension.field}. Must be one of ${Object.keys(view.dimensions)}`,\n        );\n      }\n      const dim = view.dimensions[dimension.field];\n      return {\n        ...dim,\n        table: dim.relationTable || view.name,\n        explodeArray: dim.explodeArray,\n        pairExpand: dim.pairExpand,\n      };\n    });\n  }\n\n  private mapMetrics(\n    metrics: Array<{\n      measure: string;\n      aggregation: z.infer<typeof metricAggregations>;\n    }>,","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/langfuse/langfuse/blob/59d92c7cf365150d10b753b5a0d1708902a2ed60/packages/shared/src/features/query/server/queryBuilder.ts#L263-L299","documentation":"handleDeleteMembership validates req.body against DeleteMembershipSchema before deleting. A body missing the required userId (or malformed) returns 400 'Invalid request body' with zod issue details.","triggerScenarios":"DELETE to the admin memberships endpoint with an empty body or one lacking a valid userId.","commonSituations":"DELETE requests built without a JSON body because REST intuition says DELETE carries no body, or query-param-based clients after the contract moved to body.","solutions":["Send a JSON body containing userId on the DELETE request","Include Content-Type: application/json","Check details in the 400 response for the exact failing field"],"exampleFix":"// before\nfetch(`/api/admin/organizations/${orgId}/memberships`, { method: 'DELETE' });\n// after\nfetch(`/api/admin/organizations/${orgId}/memberships`, {\n  method: 'DELETE',\n  headers: { 'Content-Type': 'application/json' },\n  body: JSON.stringify({ userId }),\n});","handlingStrategy":"validation","validationCode":"if (typeof userId !== 'string' || userId.length === 0) throw new Error('userId required in body');\nawait fetch(url, { method: 'DELETE', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ userId }) });","typeGuard":"function isDeleteMembershipBody(b: unknown): b is { userId: string } {\n  return typeof b === 'object' && b !== null && typeof (b as any).userId === 'string' && (b as any).userId.length > 0;\n}","tryCatchPattern":"const res = await fetch(url, { method: 'DELETE', ... });\nif (res.status === 400) { /* inspect details, fix body */ }","preventionTips":["Remember this DELETE expects a JSON body","Use the shared typed client for admin endpoints","Test admin scripts against a staging org"],"tags":["admin-api","zod","validation","membership","enterprise"],"backgroundTag":"request-body-validation-failed","analyzedSha":"59d92c7cf365150d10b753b5a0d1708902a2ed60","analyzedAt":"2026-08-27T22:22:00.402Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}