appsmithorg/appsmith · error · AppsmithPluginException
PE-GSH-5000
PE-GSH-5000
Error message
Missing a valid response object.
What it means
Thrown by FileInfoMethod.transformExecutionResponse (FileInfoMethod.java:117) with code PE-GSH-5000. The 'Get Spreadsheet Details' action expects a non-null JSON response from the Drive API `files/{id}?fields=...` call to merge metadata into the output map. A null response aborts the transform before `methodConfig.getBody()` is read.
Source
Thrown at app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/FileInfoMethod.java:117
@Override
public WebClient.RequestHeadersSpec<?> getExecutionClient(WebClient webClient, MethodConfig methodConfig) {
UriComponentsBuilder uriBuilder = getBaseUriBuilder(
this.BASE_DRIVE_API_URL,
methodConfig.getSpreadsheetId()
+ "?supportsAllDrives=true&fields=id,name,permissions/role,permissions/emailAddress,createdTime,modifiedTime");
return webClient
.method(HttpMethod.GET)
.uri(uriBuilder.build(false).toUri())
.body(BodyInserters.empty());
}
@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);
}
Map<String, Object> responseObj = new HashMap<>();
if (methodConfig.getBody() instanceof List) {
responseObj.put("sheets", methodConfig.getBody());
}
Iterator<String> fieldNames = response.fieldNames();
while (fieldNames.hasNext()) {
String fieldName = fieldNames.next();
responseObj.put(fieldName, response.get(fieldName));
}
return this.objectMapper.valueToTree(responseObj);
}
@Override
public boolean validateTriggerMethodRequest(MethodConfig methodConfig) {
return this.validateExecutionMethodRequest(methodConfig);View on GitHub (pinned to 8cd9021c24)
Solutions
- Enable plugin HTTP logging to capture the real status code and body from the Drive API.
- Re-authorize the Google Sheets datasource if the OAuth token expired (re-run the auth flow).
- Confirm the target spreadsheet still exists and the account has access.
- If patching the plugin, coerce a null/empty body to an empty object node before invoking transformExecutionResponse.
Example fix
// before — transform receives null
public JsonNode transformExecutionResponse(JsonNode response, ...) {
if (response == null) { throw ...; }
...
}
// after — framework coerces empty body
JsonNode node = body == null ? objectMapper.createObjectNode() : objectMapper.readTree(body);
return method.transformExecutionResponse(node, config, ids); Defensive patterns
Strategy: retry
Try / catch
// Retry once on the null-response error; it is often transient (token/expiry).
async function getInfoSafe() {
try { return await getInfo.run(); }
catch (e) {
if (e && /Missing a valid response object/.test(e.message)) {
await refreshAuth(); // re-run datasource auth if available
return await getInfo.run();
}
throw e;
}
} Prevention
- Keep the Google Sheets datasource OAuth token fresh.
- Enable HTTP logging to inspect the real Drive API response.
- Confirm the target spreadsheet still exists and is shared with the account.
When it happens
Trigger: The Drive API metadata GET returned a body that arrived as null at the transform step — e.g. an empty 204, an adapter that nulled a non-JSON error, or a Webclient filter that consumed the body. The null check is the first line of transformExecutionResponse.
Common situations: Expired/revoked OAuth token causing a non-JSON 401 that gets normalized to null; the spreadsheet was deleted between validation and the GET; a misconfigured response adapter strips the body; rate-limit (429) body lost in error mapping.
Related errors
AI-assisted analysis of appsmithorg/appsmith@8cd9021c24 (2026-08-12).
Data as JSON: /api/errors/3433478d276543d4.
Report an issue: GitHub.