Tencent/APIJSON · error · IllegalArgumentException

HEAD请求: 字符 {origin.substring(0, start)} 不合法!预编译模式下 @column:v

Error message

HEAD请求: 字符 {origin.substring(0, start)} 不合法!预编译模式下 @column:value 中 value里面用 , 分割的每一项 column:alias 中 column 必须是1个单词!如果有alias,则alias也必须为1个单词!并且不要有多余的空格!

What it means

Variant of the HEAD @column check: the item contains parentheses (so it is treated as a function call), but the function-name segment before '(' fails StringUtil.isName. In prepared mode the library requires the part before '(' to be one word, because it cannot safely parameterize an arbitrary pre-parenthesis token.

Source

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

					String alias = index < 0 ? null : c.substring(index + 1);

					if (alias != null && StringUtil.isName(alias) == false) {
						throw new IllegalArgumentException("HEAD请求: 字符 " + alias
								+ " 不合法!预编译模式下 @column:value 中 value里面用 , 分割的每一项"
								+ " column:alias 中 column 必须是1个单词!如果有alias,则alias也必须为1个单词!并且不要有多余的空格!");
					}

					if (StringUtil.isName(origin) == false) {
						int start = origin.indexOf("(");
						if (start < 0 || origin.lastIndexOf(")") <= start) {
							throw new IllegalArgumentException("HEAD请求: 字符" + origin
									+ " 不合法!预编译模式下 @column:value 中 value里面用 , 分割的每一项"
									+ " column:alias 中 column 必须是1个单词!"
									+ "如果有alias,则 alias 也必须为1个单词!并且不要有多余的空格!");
						}

						if (start > 0 && StringUtil.isName(origin.substring(0, start)) == false) {
							throw new IllegalArgumentException("HEAD请求: 字符 " + origin.substring(0, start)
									+ " 不合法!预编译模式下 @column:value 中 value里面用 , 分割的每一项"
									+ " column:alias 中 column 必须是1个单词!如果有alias,则alias也必须为1个单词!并且不要有多余的空格!");
						}
					}
				}
			}

			boolean onlyOne = column != null && column.size() == 1;
			String c0 = onlyOne ? column.get(0) : null;

			if (onlyOne) {
				int index = c0 == null ? -1 : c0.lastIndexOf(":");
				if (index > 0) {
					c0 = c0.substring(0, index);
				}

				int start = c0 == null ? -1 : c0.indexOf("(");
				int end = start <= 0 ? -1 : c0.lastIndexOf(")");

View on GitHub (pinned to 5284052872)

Solutions

  1. Remove spaces between the function name and '(': "max(id)" not "max (id)".
  2. Avoid format strings containing ':' inside HEAD @column; register such expressions in @raw/RAW_MAP on the backend instead.
  3. Do not qualify the function with a schema or package name — use the bare function name.
  4. Simplify to a single plain column for HEAD counts.

Example fix

// before
{"User":{"@column":"date_format(date,'%Y-%m-%d %H:%i:%s')"}}
// after (server-side RAW_MAP: "dateFormat" -> "date_format(date,'%Y-%m-%d %H:%i:%s')")
{"User":{"@column":"dateFormat","@raw":"@column"}}
Defensive patterns

Strategy: validation

Validate before calling

const start = expr.indexOf('(');
const name = start > 0 ? expr.slice(0, start) : expr;
if (start > 0 && !/^[A-Za-z][A-Za-z0-9_]*$/.test(name)) throw new Error('function token must be one word, no spaces before (');

Type guard

null

Try / catch

catch IllegalArgumentException; surface the offending token to the caller for correction

Prevention

When it happens

Trigger: HEAD request with "@column":"date_format(date,'%Y-%m-%d')" (the inner colons make lastIndexOf(':') split leave junk), "@column":"schema.fun(id)" (dotted prefix), or "@column":"fun (id)" (space before the parenthesis).

Common situations: Using MySQL formatting functions with format strings containing ':' which collide with the alias-splitting logic; writing SQL-style spacing (space between function name and '('); using schema-qualified functions.

Related errors


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