{"record":{"id":"08cf7a26f45ba2ae","repo":"appsmithorg/appsmith","slug":"pe-gsh-5000","errorCode":"PE-GSH-5000","errorMessage":"Missing a valid response object.","messagePattern":"Missing a valid response object\\.","errorType":"exception","errorClass":"AppsmithPluginException","httpStatus":500,"severity":"error","filePath":"app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/FileDeleteMethod.java","lineNumber":57,"sourceCode":"    @Override\n    public Mono<Object> executePrerequisites(MethodConfig methodConfig, OAuth2 oauth2) {\n        return Mono.just(true);\n    }\n\n    @Override\n    public WebClient.RequestHeadersSpec<?> getExecutionClient(WebClient webClient, MethodConfig methodConfig) {\n\n        UriComponentsBuilder uriBuilder =\n                getBaseUriBuilder(this.BASE_DRIVE_API_URL, methodConfig.getSpreadsheetId(), /* spreadsheet Id */ true);\n\n        return webClient.method(HttpMethod.DELETE).uri(uriBuilder.build(true).toUri());\n    }\n\n    @Override\n    public JsonNode transformExecutionResponse(\n            JsonNode response, MethodConfig methodConfig, Set<String> userAuthorizedSheetIds) {\n        if (response == null) {\n            throw new AppsmithPluginException(\n                    GSheetsPluginError.QUERY_EXECUTION_FAILED, ErrorMessages.MISSING_VALID_RESPONSE_ERROR_MSG);\n        }\n\n        String errorMessage = \"Deleted spreadsheet successfully!\";\n\n        return this.objectMapper.valueToTree(Map.of(\"message\", errorMessage));\n    }\n}\n","sourceCodeStart":39,"sourceCodeEnd":66,"githubUrl":"https://github.com/appsmithorg/appsmith/blob/8cd9021c24cdbea1c3c12c966073708e83db60c2/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/FileDeleteMethod.java#L39-L66","documentation":"Thrown by FileDeleteMethod.transformExecutionResponse (FileDeleteMethod.java:57) with code PE-GSH-5000 (QUERY_EXECUTION_FAILED). After the Drive API DELETE returns, the plugin expects a JSON response node to transform; if `response` is null the transform cannot proceed. On success this method returns a synthetic `{\"message\":\"Deleted spreadsheet successfully!\"}`.","triggerScenarios":"The DELETE request to the Drive API returned a 2xx with an empty/null body, or an upstream filter/adapter converted the body to null before transformExecutionResponse was called. The null check is the first statement, so any null response trips it immediately.","commonSituations":"Google Drive's DELETE endpoint legitimately returns `204 No Content` (empty body); a Webclient filter strips the body; a plugin error handler maps a non-JSON error body to null; a network layer returned an empty buffer. Since success itself has no body, a null here often indicates the response-handling pipeline rather than the API.","solutions":["Check the plugin's Webclient configuration / response adapter — a 204 with no body should be coerced to an empty object node, not null, before transform.","Inspect the actual HTTP status and body received from the Drive API (enable plugin request/response logging).","If extending the plugin, wrap `transformExecutionResponse` callers to pass `objectMapper.createObjectNode()` instead of null on empty 2xx bodies.","Verify OAuth2 credentials and scopes are still valid — an expired token can yield a non-JSON error that gets nulled out upstream."],"exampleFix":"// before (framework-level: response arrives null)\npublic JsonNode transformExecutionResponse(JsonNode response, ...) {\n    if (response == null) { throw ...; }   // trips on 204 No Content\n    ...\n}\n// after — caller coerces empty body to an object node\nJsonNode node = (body == null || body.isEmpty())\n    ? objectMapper.createObjectNode()\n    : objectMapper.readTree(body);\nreturn method.transformExecutionResponse(node, config, ids);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Wrap the action call; treat the plugin error as a likely framework/body-handling issue.\ntry {\n  await deleteSpreadsheet.run();\n} catch (e) {\n  if (e && /Missing a valid response object/.test(e.message)) {\n    // 204 No Content is a successful delete — verify via the Drive API list if needed.\n    showToast(\"Delete sent but response was empty; verify the file is gone.\", \"warning\");\n  } else { throw e; }\n}","preventionTips":["Enable plugin HTTP logging to capture the real Drive API status/body on delete.","Keep OAuth credentials fresh; expired tokens often produce non-JSON bodies that get nulled.","If maintaining the plugin, coerce empty 2xx bodies to an empty object node before transform."],"tags":["google-sheets","appsmith","response-handling","delete-spreadsheet","null-response"],"backgroundTag":null,"analyzedSha":"8cd9021c24cdbea1c3c12c966073708e83db60c2","analyzedAt":"2026-08-12T22:14:19.293Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}