termux/termux-app · error · JSONException
An key in the extra-key matrix must be a string or an object
Error message
An key in the extra-key matrix must be a string or an object
What it means
Thrown by ExtraKeysInfo.normalizeKeyConfig when an element in the extra-key matrix is neither a JSON String nor a JSONObject. The matrix is expected to be an array of arrays where each cell is a plain string (auto-wrapped to {"key": value}) or an object. Any other JSON type (number, boolean, array, null) is rejected.
Source
Thrown at termux-shared/src/main/java/com/termux/shared/termux/extrakeys/ExtraKeysInfo.java:188
}
}
return buttons;
}
/**
* Convert "value" -> {"key": "value"}. Required by
* {@link ExtraKeyButton#ExtraKeyButton(JSONObject, ExtraKeyButton, ExtraKeysConstants.ExtraKeyDisplayMap, ExtraKeysConstants.ExtraKeyDisplayMap)}.
*/
private static JSONObject normalizeKeyConfig(Object key) throws JSONException {
JSONObject jobject;
if (key instanceof String) {
jobject = new JSONObject();
jobject.put(ExtraKeyButton.KEY_KEY_NAME, key);
} else if (key instanceof JSONObject) {
jobject = (JSONObject) key;
} else {
throw new JSONException("An key in the extra-key matrix must be a string or an object");
}
return jobject;
}
public ExtraKeyButton[][] getMatrix() {
return mButtons;
}
@NonNull
public static ExtraKeysConstants.ExtraKeyDisplayMap getCharDisplayMapForStyle(String style) {
switch (style) {
case "arrows-only":
return EXTRA_KEY_DISPLAY_MAPS.ARROWS_ONLY_CHAR_DISPLAY;
case "arrows-all":
return EXTRA_KEY_DISPLAY_MAPS.LOTS_OF_ARROWS_CHAR_DISPLAY;
case "all":
return EXTRA_KEY_DISPLAY_MAPS.FULL_ISO_CHAR_DISPLAY;
case "none":View on GitHub (pinned to 3df69d1da1)
Solutions
- Ensure every cell in the matrix is either a quoted string or a JSON object.
- Quote key names that look numeric or boolean (e.g. use "1" not 1).
- Run the JSON through a validator and fix type mismatches in the matrix.
Example fix
// before (invalid: numeric cell) [["CTRL", 1], ["ALT", "TAB"]] // after (string cell) [["CTRL", "1"], ["ALT", "TAB"]]
Defensive patterns
Strategy: type-guard
Validate before calling
if (!(key instanceof String) && !(key instanceof JSONObject)) {
throw new JSONException("Matrix cell must be a string or object, got: "
+ (key == null ? "null" : key.getClass().getSimpleName()));
} Type guard
private static boolean isValidKeyCell(Object key) {
return key instanceof String || key instanceof JSONObject;
} Try / catch
try {
normalizeKeyConfig(cell);
} catch (JSONException e) {
if (e.getMessage() != null && e.getMessage().contains("must be a string or an object")) {
// coerce/quote the value or drop the cell
cell = String.valueOf(cell);
} else throw e;
} Prevention
- Ensure every matrix cell is a quoted string or a JSON object.
- Quote numerically-named keys rather than using raw numbers.
- Validate the matrix with a schema that restricts cell types.
When it happens
Trigger: The extra-keys JSON matrix contains a numeric literal (e.g. 1), a boolean (true), null, or a nested array where a button cell is expected: [["CTRL", 1], ...].
Common situations: Hand-editing the matrix and putting a number/boolean instead of a key name; malformed JSON where a key name lost its quotes; templating bug inserting a non-string token.
Related errors
- Both key and macro can't be set for the same key. key: "%s",
- All keys have to specify either key or macro
- Unsupported TERMUX_APP_PACKAGE_VARIANT "%s"
- Unsupported TERMUX_APP_PACKAGE_MANAGER "%s" with variant "%s
- Unsupported TERMUX_PACKAGE_VARIANT "%s"
AI-assisted analysis of termux/termux-app@3df69d1da1 (2026-08-13).
Data as JSON: /api/errors/1ad92714a0a14fe6.
Report an issue: GitHub.