{"record":{"id":"b0ba0b5a80c79641","repo":"prestodb/presto","slug":"lark-api-error","errorCode":"LARK_API_ERROR","errorMessage":"Illegal response data of sheet %s @ %s","messagePattern":"Illegal response data of sheet (.+?) @ (.+?)","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-lark-sheets/src/main/java/com/facebook/presto/lark/sheets/api/SimpleLarkSheetsApi.java","lineNumber":109,"sourceCode":"    public List<String> getHeaderRow(String token, String sheetId, int columnCount)\n    {\n        String lastColumnLabel = LarkSheetsUtil.columnIndexToColumnLabel(columnCount - 1);\n        String range = format(\"%s!A1:%s1\", sheetId, lastColumnLabel);\n        try {\n            SheetsService.SpreadsheetsValuesGetReqCall request = sheetsService.getSpreadsheetss().valuesGet();\n            request.setSpreadsheetToken(token);\n            request.setRange(range);\n\n            Response<SpreadsheetsValuesGetResult> response = request.execute();\n            checkResponse(response);\n            SpreadsheetsValuesGetResult data = response.getData();\n            Object[] values = data.getValueRange().getValues();\n            if (values.length == 0) {\n                throw new PrestoException(LarkSheetsErrorCode.SHEET_BAD_DATA,\n                        format(\"Sheet %s.%s is empty\", mask(token), sheetId));\n            }\n            if (!(values[0] instanceof List)) {\n                throw new PrestoException(LARK_API_ERROR,\n                        format(\"Illegal response data of sheet %s @ %s\", mask(token), range));\n            }\n            List<?> header = ((List<?>) values[0]);\n            return header.stream().map(obj -> obj == null ? null : obj.toString()).collect(Collectors.toList());\n        }\n        catch (Exception e) {\n            throw wrapApiError(e, format(\"Could not get data of sheet %s @ %s\", mask(token), range));\n        }\n    }\n\n    @Override\n    public SheetValues getValues(String token, String range)\n    {\n        try {\n            SheetsService.SpreadsheetsValuesGetReqCall request = sheetsService.getSpreadsheetss().valuesGet();\n            request.setSpreadsheetToken(token);\n            request.setRange(range);\n","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-lark-sheets/src/main/java/com/facebook/presto/lark/sheets/api/SimpleLarkSheetsApi.java#L91-L127","documentation":"In getHeaderRow, after the empty check, the code verifies values[0] is a List (a row of cells). If the first element is not a List the Lark API returned data in an unexpected shape, and LARK_API_ERROR is thrown. This indicates a malformed or unexpected API payload rather than user data problems.","triggerScenarios":"The Lark values API returns a values array whose first element is not a List (e.g. scalar values, null structure, or an SDK shape change after a Lark client library upgrade).","commonSituations":"Lark API version/SDK update changing the response structure; proxy or mock returning non-standard JSON; corrupted cached responses.","solutions":["Upgrade or pin the Lark SDK client library to a version matching the connector's expectations.","Log the raw response payload to inspect the unexpected shape.","Catch PrestoException with LARK_API_ERROR and retry or fall back to re-fetching the range."],"exampleFix":"// before\nObject[] values = data.getValueRange().getValues();\n\n// after (defensive)\nObject[] values = data.getValueRange() != null && data.getValueRange().getValues() != null\n        ? data.getValueRange().getValues() : new Object[0];","handlingStrategy":"retry","validationCode":"// preflight: fetch values and check first element shape before dependent logic\nObject[] values = /* from getValueRange */;\nif (values.length == 0 || !(values[0] instanceof List)) throw new IllegalStateException(\"Unexpected Lark payload shape\");","typeGuard":"boolean hasListHeader(Object[] values) { return values != null && values.length > 0 && values[0] instanceof List; }","tryCatchPattern":"try { header = api.getHeaderRow(token, sheetId, range); } catch (PrestoException e) { if (isLarkApiError(e) && e.getMessage().startsWith(\"Illegal response data\")) { header = retryWithBackoff(3); } else { throw e; } }","preventionTips":["Pin the Lark SDK version and test after upgrades.","Log raw responses to detect shape drift early.","Add retry with backoff around header reads."],"tags":["api-response","malformed-data","presto"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}