Tencent/APIJSON · error · UnsupportedOperationException

@raw:value 的 value 中 {key} 不合法!对应的 {key}:value 中 value 类型只能为

Error message

@raw:value 的 value 中 {key} 不合法!对应的 {key}:value 中 value 类型只能为 String!

What it means

gainRawSQL throws when @raw lists a key (e.g. "@raw": ["@column"]) but the corresponding sibling value in the request is not a String. @raw means 'insert the matching value's pre-approved SQL from RAW_MAP', and RAW_MAP keys are strings — a non-string value can never match and is rejected up front.

Source

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

		return gainRawSQL(key, value, ! ALLOW_MISSING_KEY_4_COMBINE);
	}
	/**获取原始 SQL 片段
	 * @param key
	 * @param value
	 * @param throwWhenMissing
	 * @return
	 * @throws Exception
	 */
	@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;
			}
		}

View on GitHub (pinned to 5284052872)

Solutions

  1. Make the @raw-referenced value a string: "@having": "myFilter"
  2. Ensure the string is a key configured in backend RAW_MAP
  3. Keep @raw list and the flagged fields in sync when renaming keys

Example fix

// before
{"@raw": "@having", "@having": 123}
// after
{"@raw": "@having", "@having": "myFilter"}
Defensive patterns

Strategy: type-guard

Validate before calling

const rawList = Array.isArray(obj['@raw']) ? obj['@raw'] : (obj['@raw'] ? [obj['@raw']] : []);
for (const k of rawList) {
  if (k in obj && typeof obj[k] !== 'string') throw new Error(`@raw target ${k} must hold a string token, got ${typeof obj[k]}`);
}

Type guard

const isRawTargetString = (obj, k) => typeof obj[k] === 'string';

Try / catch

try { await api.get(req); } catch (e) { if (e.message.includes('value 类型只能为 String')) coerceRawTargetsToString(req); else throw e; }

Prevention

When it happens

Trigger: {"@raw": "@having", "@having": 123} or "@having": ["a"] — the referenced key exists in @raw but its value is a number/array/object instead of a String.

Common situations: Client sets the @raw-flagged field from untyped form input that arrives as a number; renaming fields so @raw points at a field that now holds structured data.

Related errors


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