{"record":{"id":"14ad9edbf1d1e072","repo":"tursodatabase/turso","slug":"column-name-columnlabel-not-found","errorCode":null,"errorMessage":"column name {columnLabel} not found","messagePattern":"column name (.+?) not found","errorType":"exception","errorClass":"SQLException","httpStatus":null,"severity":"error","filePath":"bindings/java/src/main/java/tech/turso/jdbc4/JDBC4ResultSet.java","lineNumber":443,"sourceCode":"  @Override\n  @SkipNullableCheck\n  public Object getObject(String columnLabel) throws SQLException {\n    return getObject(findColumn(columnLabel));\n  }\n\n  @Override\n  public int findColumn(String columnLabel) throws SQLException {\n    if (columnLabel == null || columnLabel.isEmpty()) {\n      throw new SQLException(\"column name not found\");\n    }\n\n    final String[] columnNames = resultSet.getColumnNames();\n    for (int i = 0; i < columnNames.length; i++) {\n      if (columnNames[i].equals(columnLabel)) {\n        return i + 1;\n      }\n    }\n    throw new SQLException(\"column name \" + columnLabel + \" not found\");\n  }\n\n  @Override\n  @SkipNullableCheck\n  public Reader getCharacterStream(int columnIndex) throws SQLException {\n    final Object result = resultSet.get(columnIndex);\n    wasNull = result == null;\n    if (result == null) {\n      return null;\n    }\n    return wrapTypeConversion(() -> new StringReader((String) result));\n  }\n\n  @Override\n  @Nullable\n  public Reader getCharacterStream(String columnLabel) throws SQLException {\n    return getCharacterStream(findColumn(columnLabel));\n  }","sourceCodeStart":425,"sourceCodeEnd":461,"githubUrl":"https://github.com/tursodatabase/turso/blob/bad083fafbefdeae9a42ec19bdaaad8918dcf411/bindings/java/src/main/java/tech/turso/jdbc4/JDBC4ResultSet.java#L425-L461","documentation":"findColumn() throws 'column name <label> not found' after scanning resultSet.getColumnNames() without a match. The match is exact and case-sensitive (String.equals), so only the precise label the query produced - alias included - is accepted.","triggerScenarios":"Case mismatch ('ID' vs 'id'); expressions without aliases (SELECT COUNT(*) must be aliased AS cnt to be addressable); using the base column name when the SELECT aliases it differently; typos; labels carrying leading/trailing whitespace from config files.","commonSituations":"Porting from drivers that fall back to case-insensitive matching; dynamic query builders where the SELECT list and the Java reader disagree; UNION queries whose branches alias differently; SQL copied with the alias dropped.","solutions":["Use the exact label the query defines, including the AS alias (SELECT COUNT(*) AS cnt -> 'cnt')","Alias every expression in the SELECT list so labels are stable and queryable","Enumerate rs.getMetaData().getColumnLabel(i) for i in 1..getColumnCount() at debug level to see the real labels","Trim and constant-case labels on both the SQL and Java sides"],"exampleFix":"// before\nint n = rs.getInt(\"count\"); // query was SELECT COUNT(*) AS cnt\n\n// after\nint n = rs.getInt(\"cnt\");\n// or make both sides explicit:\n// SELECT COUNT(*) AS count_total ...  ->  rs.getInt(\"count_total\")","handlingStrategy":"validation","validationCode":"// Verify the label exists (exact, case-sensitive match) before reading\njava.sql.ResultSetMetaData md = rs.getMetaData();\nboolean found = false;\nfor (int i = 1; i <= md.getColumnCount(); i++) {\n  if (md.getColumnLabel(i).equals(label)) { found = true; break; }\n}\nif (!found) {\n  throw new IllegalArgumentException(\"unknown label '\" + label + \"'; actual: \"\n      + labelsOf(md));\n}","typeGuard":"static boolean hasColumn(java.sql.ResultSet rs, String label) throws SQLException {\n  if (label == null || label.isEmpty()) return false;\n  java.sql.ResultSetMetaData md = rs.getMetaData();\n  for (int i = 1; i <= md.getColumnCount(); i++) {\n    if (label.equals(md.getColumnLabel(i))) return true;\n  }\n  return false;\n}","tryCatchPattern":"try {\n  int v = rs.getInt(label);\n} catch (SQLException e) {\n  if (!String.valueOf(e.getMessage()).contains(\"not found\")) throw e;\n  // dump actual labels for a quick fix\n  java.sql.ResultSetMetaData md = rs.getMetaData();\n  for (int i = 1; i <= md.getColumnCount(); i++) log.error(\"column {}: {}\", i, md.getColumnLabel(i));\n  throw e;\n}","preventionTips":["Alias every expression in SELECT lists so labels are stable","Keep SQL label constants in one file shared with reader code","Remember matching here is case-sensitive - use the exact spelling and alias"],"tags":["java","jdbc","turso","column-lookup","sql-alias","case-sensitivity"],"backgroundTag":"jdbc-column-not-found","analyzedSha":"bad083fafbefdeae9a42ec19bdaaad8918dcf411","analyzedAt":"2026-08-16T23:12:11.798Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}