{"record":{"id":"7c8eea07abbf5683","repo":"JetBrains/intellij-community","slug":"unable-to-set-value-no-gridrow-found-at-row-inde","errorCode":null,"errorMessage":"\"Unable to set value. No GridRow found at row index: \" + rowIdx","messagePattern":"\"Unable to set value\\. No GridRow found at row index: \" \\+ rowIdx","errorType":"validation","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"grid/core-impl/src/datagrid/GridWrapperNestedTable.java","lineNumber":38,"sourceCode":"  public ColumnNamesHierarchyNode getColumnsHierarchy() {\n    return null;\n  }\n\n  @Override\n  public Object getValueAt(int rowIdx, int colIdx) {\n    return myGridModel.getValueAt(ModelIndex.forRow(myGridModel, rowIdx), ModelIndex.forColumn(myGridModel, colIdx));\n  }\n\n  @Override\n  public Object getValueAt(GridRow row, GridColumn column) {\n    return myGridModel.getValueAt(row, column);\n  }\n\n  @Override\n  public void setValueAt(int rowIdx, int colIdx, Object value) {\n    GridRow row = myGridModel.getRow(ModelIndex.forRow(myGridModel, rowIdx));\n    if (row == null) {\n      throw new IllegalStateException(\"Unable to set value. No GridRow found at row index: \" + rowIdx);\n    }\n    row.setValue(colIdx, value);\n  }\n\n  @Override\n  public void addRow(GridRow value) {\n    myGridModel.addRow(value);\n  }\n\n  @Override\n  public int getRowsNum() {\n    return myGridModel.getRowCount();\n  }\n\n  @Override\n  public int getColumnsNum() {\n    return myGridModel.getColumnCount();\n  }","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/JetBrains/intellij-community/blob/be881553f2a76ac8b4ea53950d93f0de78295c19/grid/core-impl/src/datagrid/GridWrapperNestedTable.java#L20-L56","documentation":"GridWrapperNestedTable.setValueAt(int, int, Object) throws IllegalStateException when the wrapped grid model returns null from getRow(ModelIndex.forRow(model, rowIdx)). The wrapper cannot delegate row.setValue(colIdx, value) without a live GridRow, so a null row at the given view index is a state error (not an argument problem).","triggerScenarios":"Calling setValueAt on a row index that is filtered out, beyond the model's row count, or whose row was disposed between UI event and write-back (e.g. after a quick search filter or sorting pass removed it).","commonSituations":"An editor commit fired after the model was refreshed; setValueAt queued on a background thread while the EDT removed rows; index taken from a stale GridRow reference.","solutions":["Verify the row exists first: myGridModel.getRow(ModelIndex.forRow(model, rowIdx)) != null, or isValidRowIdx(rowIdx).","Re-obtain the row index from the current selection/event right before writing the value.","Perform model mutation and value write on the same dispatch thread with no intervening refresh."],"exampleFix":"// before\nwrapperTable.setValueAt(rowIdx, colIdx, value);\n\n// after\nif (wrapperTable.isValidRowIdx(rowIdx)) {\n  wrapperTable.setValueAt(rowIdx, colIdx, value);\n}","handlingStrategy":"validation","validationCode":"if (wrapperTable.isValidRowIdx(rowIdx)) {\n  wrapperTable.setValueAt(rowIdx, colIdx, value);\n} else {\n  LOG.warn(\"row \" + rowIdx + \" no longer present; value dropped\");\n}","typeGuard":null,"tryCatchPattern":"try { wrapperTable.setValueAt(rowIdx, colIdx, value); } catch (IllegalStateException e) { // row vanished: user-visible refresh, do not crash LOG.warn(e.getMessage()); }","preventionTips":["Write cell values on the EDT in the same transaction that validated the row exists.","Re-read the row from the model at commit time instead of trusting indexes from the event."],"tags":["datagrid","grid-wrapper","state-error","row-disposed"],"backgroundTag":null,"analyzedSha":"be881553f2a76ac8b4ea53950d93f0de78295c19","analyzedAt":"2026-08-14T14:13:06.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}