appsmithorg/appsmith · error · AppsmithPluginException
PLUGIN_EXECUTE_ARGUMENT_ERROR
PLUGIN_EXECUTE_ARGUMENT_ERROR
Error message
Expected a row object, but did not find it.
What it means
Thrown by private getRowObjectFromBody in RowsUpdateMethod (line 251) when body.isArray() is true. This method expects a single JSON object (row), not an array of rows. It is invoked from validateExecutionMethodRequest via objectMapper.readTree(body), so an array-shaped JSON in the 'Rows' field for an Update One Row action triggers it. Note: the code uses AppsmithPluginError.PLUGIN_EXECUTE_ARGUMENT_ERROR directly (PLUGIN_EXECUTE_ARGUMENT_ERROR as the code string, not PE-ARG-5000). Message: EXPECTED_ROW_OBJECT_MESSAGE = "Expected a row object, but did not find it.".
Source
Thrown at app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/RowsUpdateMethod.java:251
"majorDimension", "ROWS",
"values", List.of(objects))));
}
@Override
public JsonNode transformExecutionResponse(
JsonNode response, MethodConfig methodConfig, Set<String> userAuthorizedSheetIds) {
if (response == null) {
throw new AppsmithPluginException(
GSheetsPluginError.QUERY_EXECUTION_FAILED, ErrorMessages.MISSING_VALID_RESPONSE_ERROR_MSG);
}
return this.objectMapper.valueToTree(Map.of("message", "Updated sheet successfully!"));
}
private RowObject getRowObjectFromBody(JsonNode body) {
if (body.isArray()) {
throw new AppsmithPluginException(
AppsmithPluginError.PLUGIN_EXECUTE_ARGUMENT_ERROR, ErrorMessages.EXPECTED_ROW_OBJECT_MESSAGE);
}
if (body.isEmpty()) {
throw new AppsmithPluginException(
AppsmithPluginError.PLUGIN_EXECUTE_ARGUMENT_ERROR, ErrorMessages.EMPTY_UPDATE_ROW_OBJECT_MESSAGE);
}
return new RowObject(this.objectMapper.convertValue(
body,
TypeFactory.defaultInstance()
.constructMapType(LinkedHashMap.class, String.class, String.class)))
.initialize();
}
@Override
public void replaceMethodConfigTemplate(Map<String, Object> formData, Map<String, String> mappedColumns) {
String rowObjects = PluginUtils.getTrimmedStringDataValueSafelyFromFormData(formData, FieldName.ROW_OBJECTS);View on GitHub (pinned to 8cd9021c24)
Solutions
- For Update Single Row, bind to a single object: {{ JSON.stringify(Table1.selectedRow) }} (no array).
- If updating many rows, switch the command to the bulk Update Rows action.
- Coerce an array of length 1 to its first element: {{ JSON.stringify(arr[0]) }}.
- Pre-validate: JSON.parse(value) returns a non-array object.
Example fix
// Before (array passed to single-row update)
{{ JSON.stringify(Table1.selectedRows) }}
// After (single row)
{{ JSON.stringify(Table1.selectedRow) }}
// or take the first:
{{ JSON.stringify((Table1.selectedRows || [])[0]) }} Defensive patterns
Strategy: type-guard
Validate before calling
function pickRowObject(value) {
if (Array.isArray(value)) return value.length === 1 ? value[0] : null; // single-row action
if (value && typeof value === 'object') return value;
return null;
}
const row = pickRowObject(Table1.selectedRows || Table1.selectedRow);
if (!row) showAlert('Select a single row to update', 'error');
else UpdateRow.run({ rowObjects: JSON.stringify(row) }); Type guard
function isSingleRowObject(v) {
return v != null && typeof v === 'object' && !Array.isArray(v);
} Prevention
- For Update Single Row, always bind to a single object, never an array.
- Use the bulk action for arrays of rows.
- Coerce [onlyRow] to onlyRow before binding.
When it happens
Trigger: User put [{...}] (array) in the 'Rows' field of an Update Single Row action instead of {...}; a binding like {{ JSON.stringify(Table1.selectedRows) }} returns an array but the action expects one row.
Common situations: Confusion between 'Update Row' (single object) and 'Bulk Update Rows' (array); selecting multiple table rows then calling the single-row update; reusing a binding from a bulk action.
Related errors
AI-assisted analysis of appsmithorg/appsmith@8cd9021c24 (2026-08-12).
Data as JSON: /api/errors/2aa6c0d0f34df9e3.
Report an issue: GitHub.