{"record":{"id":"40d9012095cc364e","repo":"appsmithorg/appsmith","slug":"pe-gsh-5000-40d901","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/GetStructureMethod.java","lineNumber":110,"sourceCode":"                if (tableHeaderIndex <= 0) {\n                    tableHeaderIndex = 1;\n                }\n            } catch (NumberFormatException e) {\n                // Should have already been caught\n            }\n        }\n\n        return List.of(\n                \"'\" + methodConfig.getSheetName() + \"'!\" + tableHeaderIndex + \":\" + tableHeaderIndex,\n                \"'\" + methodConfig.getSheetName() + \"'!\" + (tableHeaderIndex + rowOffset + 1) + \":\"\n                        + (tableHeaderIndex + rowOffset + rowLimit));\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        ArrayNode valueRanges = (ArrayNode) response.get(\"valueRanges\");\n        ArrayNode headers = (ArrayNode) valueRanges.get(0).get(\"values\");\n        ArrayNode values =\n                valueRanges.get(1) != null ? (ArrayNode) valueRanges.get(1).get(\"values\") : null;\n        int valueSize = 0;\n\n        if (headers == null || headers.isEmpty()) {\n            return this.objectMapper.createArrayNode();\n        }\n        if (values != null) {\n            for (int i = 0; i < values.size(); i++) {\n                valueSize = Math.max(valueSize, values.get(i).size());\n            }\n        }\n","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/appsmithorg/appsmith/blob/8cd9021c24cdbea1c3c12c966073708e83db60c2/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/GetStructureMethod.java#L92-L128","documentation":"Thrown by GetStructureMethod.transformExecutionResponse (GetStructureMethod.java:110) with code PE-GSH-5000. After the Sheets API `values:batchGet` returns, the transform reads `response.get(\"valueRanges\")` to extract headers and sample rows. If the response node itself is null, it throws before that read.","triggerScenarios":"The batchGet request returned a body that arrived null at the transform — empty body, a nulled non-JSON error, or a Webclient filter consuming the body. The null guard is the first statement of transformExecutionResponse.","commonSituations":"OAuth token expired (401 body nulled upstream); the requested range/sheet does not exist so the API returned an unexpected empty body; transient network failure returning empty; rate limit (429) error body lost in error mapping.","solutions":["Re-authorize the Google Sheets datasource if the OAuth token expired.","Enable plugin HTTP logging to capture the real status and body.","Confirm the sheet name and range in the request are valid and exist.","If patching the plugin, coerce a null body to an empty object node before invoking transformExecutionResponse."],"exampleFix":"// before — batchGet body arrives null\npublic JsonNode transformExecutionResponse(JsonNode response, ...) {\n    if (response == null) { throw ...; }\n    ArrayNode valueRanges = (ArrayNode) response.get(\"valueRanges\");\n    ...\n}\n// after — caller coerces empty\nJsonNode node = body == null ? objectMapper.createObjectNode() : objectMapper.readTree(body);\nreturn method.transformExecutionResponse(node, config, ids);","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"async function getStructureSafe() {\n  try { return await getStructure.run(); }\n  catch (e) {\n    if (e && /Missing a valid response object/.test(e.message)) {\n      await refreshToken();\n      return await getStructure.run();\n    }\n    throw e;\n  }\n}","preventionTips":["Keep OAuth credentials valid to avoid non-JSON 401 bodies being nulled.","Verify the sheet name and range exist before reading structure.","Enable HTTP logging to inspect the batchGet response."],"tags":["google-sheets","appsmith","response-handling","get-structure","null-response"],"backgroundTag":null,"analyzedSha":"8cd9021c24cdbea1c3c12c966073708e83db60c2","analyzedAt":"2026-08-12T22:14:19.293Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}