Tencent/APIJSON · error · UnsupportedOperationException

@raw:value 的 value 中 {key} 不合法!对应的 {key}:value 中 value 值 {va

Error message

@raw:value 的 value 中 {key} 不合法!对应的 {key}:value 中 value 值 {value} 未在后端 RAW_MAP 中配置 !

What it means

gainRawSQL with throwWhenMissing: the @raw-flagged value is a String but is not a key in the backend RAW_MAP (or maps to nothing). RAW_MAP is the server-side whitelist that turns a client token into fixed SQL; an unconfigured token is refused rather than passed through, preventing arbitrary SQL.

Source

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

	 */
	@Override
	public String gainRawSQL(String key, Object value, boolean throwWhenMissing) throws Exception {
		if (value == null) {
			return null;
		}

		List<String> rawList = getRaw();
		boolean containRaw = rawList != null && rawList.contains(key);
		if (containRaw && value instanceof String == false) {
			throw new UnsupportedOperationException("@raw:value 的 value 中 " + key + " 不合法!"
					+ "对应的 " + key + ":value 中 value 类型只能为 String!");
		}

		String rawSQL = containRaw ? RAW_MAP.get(value) : null;
		if (containRaw) {
			if (rawSQL == null) {
				if (throwWhenMissing) {
					throw new UnsupportedOperationException("@raw:value 的 value 中 " + key + " 不合法!"
							+ "对应的 " + key + ":value 中 value 值 " + value + " 未在后端 RAW_MAP 中配置 !");
				}

				putWarnIfNeed(JSONMap.KEY_RAW, "@raw:value 的 value 中 "
							+ key + " 不合法!对应的 " + key + ":value 中 value 值 " + value + " 未在后端 RAW_MAP 中配置 !");
			}
			else if (rawSQL.isEmpty()) {
				return (String) value;
			}
		}

		return rawSQL;
	}


	@Override
	public List<String> getJson() {
		return json;

View on GitHub (pinned to 5284052872)

Solutions

  1. Backend: add the token to RAW_MAP (e.g. RAW_MAP.put("customExpr", "toYYYYMM(date)")) and reload
  2. Use only tokens you know are configured; expose the available tokens to the frontend
  3. If throwWhenMissing is false in your path this becomes a warning instead — but do not rely on that for writes

Example fix

// backend: APIJSONApplication.init() 
// AbstractSQLConfig.RAW_MAP.put("ymExpr", "toYYYYMM(created_at)");
// request: {"@raw": "@column", "@column": "ymExpr"}
Defensive patterns

Strategy: validation

Validate before calling

const RAW_TOKENS = new Set(['ymExpr', 'statusCase']); // mirror of backend RAW_MAP keys
for (const k of rawListOf(obj)) {
  const tok = obj[k];
  if (typeof tok === 'string' && !RAW_TOKENS.has(tok)) throw new Error(`@raw token '${tok}' is not configured in backend RAW_MAP`);
}

Type guard

const isKnownRawToken = (tok, known) => typeof tok === 'string' && known.has(tok);

Try / catch

try { await api.get(req); } catch (e) { if (e.message.includes('未在后端 RAW_MAP 中配置')) surfaceConfigErrorToAdmin(req, e); else throw e; }

Prevention

When it happens

Trigger: {"@raw": "@column", "@column": "customExpr"} where customExpr was never added to RAW_MAP on the server; using a token valid on one deployment against another that lacks it.

Common situations: Environment drift: token configured in dev RAW_MAP but not production; upgrading APIJSON resets a programmatically-built RAW_MAP; typo between the token in code and the map key.

Related errors


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