{"record":{"id":"4063dd1c6186c40d","repo":"hs-web/hsweb-framework","slug":"alias-dimension-type-not","errorCode":null,"errorMessage":"查询条件错误,正确格式:${alias}$dimension${type}$[not]","messagePattern":"查询条件错误,正确格式:(.+?)\\$dimension(.+?)\\$\\[not\\]","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/java/org/hswebframework/web/system/authorization/defaults/service/terms/DimensionTerm.java","lineNumber":73,"sourceCode":"        if (not) {\n            joiner.add(\"not\");\n        }\n        if (any) {\n            joiner.add(\"any\");\n        }\n        return joiner.toString();\n    }\n\n    @Override\n    public SqlFragments createFragments(String columnFullName, RDBColumnMetadata column, Term term) {\n\n        List<Object> values = convertList(column, term);\n        if (values.isEmpty()) {\n            return EmptySqlFragments.INSTANCE;\n        }\n        List<String> options = term.getOptions();\n        if (CollectionUtils.isEmpty(options)) {\n            throw new IllegalArgumentException(\"查询条件错误,正确格式:\" + column.getAlias() + \"$dimension${type}$[not]\");\n        }\n        BatchSqlFragments fragments = new BatchSqlFragments(6, 2);\n\n        if (options.contains(\"not\")) {\n            fragments.add(SqlFragments.NOT);\n        }\n        fragments\n            .addSql(\"exists(select 1 from\",\n                    getTableName(\"s_dimension_user\", column),\n                    \"d where d.dimension_type_id = ? and d.dimension_id =\", columnFullName)\n            .addParameter(options.get(0));\n\n        if (!options.contains(\"any\")) {\n            fragments\n                .add(USER_ID_IN)\n                .add(SqlUtils.createQuestionMarks(values.size()))\n                .add(SqlFragments.RIGHT_BRACKET)\n                .addParameter(values);","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/hs-web/hsweb-framework/blob/b2cfc85a57c70bf5b5cf6e7edae2d37102652ec8/hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/java/org/hswebframework/web/system/authorization/defaults/service/terms/DimensionTerm.java#L55-L91","documentation":"IllegalArgumentException thrown by DimensionTerm.createFragments when a dynamic-query term targeting an authorization dimension has no options. The $dimension term requires its options to carry the dimension type (and optionally 'not'), because it must build SQL fragments like alias$type$[not]; without options the term is meaningless and the query cannot be compiled. This is a caller misuse of the query DSL, not a server fault.","triggerScenarios":"Building an authorization query with a term keyed like 'dimension' (e.g. createQuery().is(\"dimension$dimension\", ...) or passing request parameters such as dimension$type=...) but omitting the type segment in the term options — i.e. term.getOptions() returns null or an empty list.","commonSituations":"Front-end query strings missing the '$dimension$type' suffix on the column name; copying a query example and dropping the [not] or type option; constructing terms programmatically with DimensionTerm but forgetting to set options.","solutions":["Include the dimension type in the term key/options, e.g. use the column alias as alias$dimension$type (type = the dimension type id such as user/role).","If negation is needed, add the 'not' option: alias$dimension$type$[not].","For programmatic use, set the options list on the term before createFragments is invoked.","Check the incoming query-string parameter names for typos that swallow the '$dimension$type' segment."],"exampleFix":"// before\ncreateQuery().is(\"dimension$dimension\", \"role-id-1\")\n// after\ncreateQuery().is(\"dimension$dimension$role\", \"role-id-1\") // type segment present in options","handlingStrategy":"validation","validationCode":"String key = \"dimension$dimension$\" + dimensionType;\nif (dimensionType == null || dimensionType.isBlank()) {\n    throw new IllegalArgumentException(\"dimension term requires a type option, e.g. dimension$dimension$user\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    return service.createQuery().is(key, value).fetch();\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"$dimension\")) {\n        throw new BadRequestException(\"查询条件需形如 column$dimension$type$[not]\");\n    }\n    throw e;\n}","preventionTips":["Build dimension terms via a helper that always appends the type segment.","Unit-test query DSL strings used by the front end.","Never hand-strip the '$type' suffix from copied examples.","Document the alias$dimension$type$[not] format in API docs."],"tags":["query-dsl","authorization","validation","hsweb"],"backgroundTag":"invalid-argument-format","analyzedSha":"b2cfc85a57c70bf5b5cf6e7edae2d37102652ec8","analyzedAt":"2026-09-13T09:05:02.172Z","contentChangedAt":"2026-09-13T09:05:02.172Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}