appsmithorg/appsmith · error · AppsmithPluginException
PE-ARG-5000
PE-ARG-5000
Error message
Unexpected value for table header index. Please use a number starting from 1
What it means
Thrown by GetStructureMethod.validateExecutionMethodRequest (GetStructureMethod.java:51) when `tableHeaderIndex` is a valid integer but is `<= 0`. The table header index marks the 1-based row that holds column headers, so zero or negative values are invalid. Code PE-ARG-5000 (INVALID_TABLE_HEADER_INDEX).
Source
Thrown at app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/GetStructureMethod.java:51
public GetStructureMethod(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
this.filterDataService = FilterDataService.getInstance();
}
// Used to capture the range of columns in this request. The handling for this regex makes sure that
// all possible combinations of A1 notation for a range map to a common format
Pattern findAllRowsPattern = Pattern.compile("([a-zA-Z]*)\\d*:([a-zA-Z]*)\\d*");
// The starting row for a range is captured using this pattern to find its relative index from table heading
Pattern findOffsetRowPattern = Pattern.compile("(\\d+):");
@Override
public boolean validateExecutionMethodRequest(MethodConfig methodConfig) {
if (methodConfig.getTableHeaderIndex() != null
&& !methodConfig.getTableHeaderIndex().isBlank()) {
try {
if (Integer.parseInt(methodConfig.getTableHeaderIndex()) <= 0) {
throw new AppsmithPluginException(
AppsmithPluginError.PLUGIN_EXECUTE_ARGUMENT_ERROR,
ErrorMessages.INVALID_TABLE_HEADER_INDEX);
}
} catch (NumberFormatException e) {
throw new AppsmithPluginException(
AppsmithPluginError.PLUGIN_EXECUTE_ARGUMENT_ERROR, ErrorMessages.INVALID_TABLE_HEADER_INDEX);
}
} else {
throw new AppsmithPluginException(
AppsmithPluginError.PLUGIN_EXECUTE_ARGUMENT_ERROR, ErrorMessages.INVALID_TABLE_HEADER_INDEX);
}
return true;
}
@Override
public WebClient.RequestHeadersSpec<?> getExecutionClient(WebClient webClient, MethodConfig methodConfig) {
final List<String> ranges = validateInputs(methodConfig);View on GitHub (pinned to 8cd9021c24)
Solutions
- Set `tableHeaderIndex` to a 1-based row number, e.g. `1` if headers are in the first row.
- If computing dynamically, clamp the result to at least 1: `Math.max(1, currentIndex)`.
- Remember: table header index is 1-based, unlike the separate row-index field which is 0-based.
Example fix
// before
{
"tableHeaderIndex": 0 // 0-based mistake
}
// after
{
"tableHeaderIndex": 1 // 1-based: first row holds headers
} Defensive patterns
Strategy: validation
Validate before calling
// Clamp any computed header index to a 1-based positive integer before submit.
function headerIndex(value) {
const n = Math.trunc(Number(value));
return Number.isFinite(n) && n >= 1 ? String(n) : "1";
}
// Bind tableHeaderIndex: {{ headerIndex(someWidget.value) }} Type guard
function isValidHeaderIndex(v) {
const n = Number(v);
return Number.isInteger(n) && n >= 1;
} Try / catch
if (getStructure.error && /table header index/.test(getStructure.error.message)) {
showToast("Table header index must be a whole number >= 1.", "error");
} Prevention
- Treat table header index as 1-based (unlike row-index fields which are 0-based).
- Clamp dynamically computed indices with Math.max(1, n).
- Default the field to 1 for typical first-row headers.
When it happens
Trigger: The 'Get Structure' / read action runs with `tableHeaderIndex` set to `0`, a negative number, or a numeric expression that evaluates to <= 0 (e.g. `{{rowIdx - 5}}` when rowIdx is small). `Integer.parseInt` succeeds, then the `<= 0` branch throws.
Common situations: User assumes a 0-based row index and enters `0`; a mustache binding computes the index and underflows (e.g. `{{currentIndex - offset}}`); default value mistakenly set to `0`; copying config from a row-index field (which is 0-based) into the header-index field (1-based).
Related errors
AI-assisted analysis of appsmithorg/appsmith@8cd9021c24 (2026-08-12).
Data as JSON: /api/errors/66dd34c284014460.
Report an issue: GitHub.