Tencent/APIJSON · error · IllegalArgumentException

字符串 {ck} 不合法!预编译模式下 @column:"column0,column1:alias;function0

Error message

字符串 {ck} 不合法!预编译模式下 @column:"column0,column1:alias;function0(arg0,arg1,...);function1(...):alias..." 中字符串参数不合法,必须以 ' 开头, ' 结尾,字符串中不能包含 ' 

What it means

A single-quoted argument inside a function expression is unquoted; if the inner content itself contains a single quote, this IllegalArgumentException fires. Quotes cannot be escaped in this DSL position, so any embedded apostrophe terminates the literal and is rejected as an injection risk.

Source

Thrown at APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java:2703

				String origin;
				String alias;

				// 如果参数包含 "'" ,解析字符串
				if (ck.startsWith("`") && ck.endsWith("`")) {
					origin = ck.substring(1, ck.length() - 1);
					//sql 注入判断 判断
					if (origin.startsWith("_") || StringUtil.isName(origin) == false) {
						throw new IllegalArgumentException("字符 " + ck + " 不合法!"
								+ "预编译模式下 @column:\"`column0`,`column1`:alias;function0(arg0,arg1,...);function1(...):alias...\""
								+ " 中所有字符串 column 都必须必须为1个单词 !");
					}

					origin = gainKey(origin);
				}
				else if (ck.startsWith("'") && ck.endsWith("'")) {
					origin = ck.substring(1, ck.length() - 1);
					if (origin.contains("'")) {
						throw new IllegalArgumentException("字符串 " + ck + " 不合法!"
								+ "预编译模式下 @column:\"column0,column1:alias;function0(arg0,arg1,...);function1(...):alias...\""
								+ " 中字符串参数不合法,必须以 ' 开头, ' 结尾,字符串中不能包含 ' ");
					}

					// 1.字符串不是字段也没有别名,所以不解析别名 2. 是字符串,进行预编译,使用getValue() ,对字符串进行截取
					origin = gainValue(origin).toString();
				}
				else {
					// 参数不包含",",即不是字符串
					// 解析参数:1. 字段 ,2. 是以空格分隔的参数 eg: cast(now() as date)
					if ("=null".equals(ck)) {
						origin = SQL.isNull();
					}
					else if ("!=null".equals(ck)) {
						origin = SQL.isNull(false);
					}
					else {
						origin = ck;

View on GitHub (pinned to 5284052872)

Solutions

  1. Remove the inner quote from the literal, or pass the value as a parameter elsewhere (e.g. @having with precompiled values).
  2. For literal apostrophes, define the expression in @raw server-side where full SQL escaping is available.
  3. Choose literals that do not require embedded quotes.

Example fix

// before
{"User":{"@column":"replace(name,','',' ')"}}
// after — server RAW_MAP.put("cleanName", "replace(name, ',', ' ')")
{"User":{"@column":"cleanName","@raw":"@column"}}
Defensive patterns

Strategy: validation

Validate before calling

for(const arg of args){ if(arg.startsWith("'")&&arg.endsWith("'")){ if(arg.slice(1,-1).includes("'"))throw new Error('literal cannot contain a quote'); } }

Type guard

function isQuotedArg(a) { return !(a.startsWith("'") && a.endsWith("'") && a.slice(1, -1).includes("'")); }

Try / catch

catch IllegalArgumentException; move the literal server-side via @raw and retry

Prevention

When it happens

Trigger: "@column":"replace(name,','',' ')" where the first literal contains an embedded quote; searching for an apostrophe in text; fuzzed payloads like "concat('a'b')".

Common situations: Text-processing functions operating on strings that contain apostrophes (names like O'Brien); client-side escaping using doubled quotes (SQL style) which this parser does not accept here.

Related errors


AI-assisted analysis of Tencent/APIJSON@5284052872 (2026-08-14). Data as JSON: /api/errors/922f517c1e50163e. Report an issue: GitHub.