{"record":{"id":"571bb58b5de43fb8","repo":"pentaho/pentaho-kettle","slug":"jobhopmeta-exception-unabletoloadhopinforep","errorCode":null,"errorMessage":"JobHopMeta.Exception.UnableToLoadHopInfoRep","messagePattern":"JobHopMeta\\.Exception\\.UnableToLoadHopInfoRep","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/repository/kdr/delegates/KettleDatabaseRepositoryJobDelegate.java","lineNumber":654,"sourceCode":"        long id_jobentry_copy_from = r.getInteger( \"ID_JOBENTRY_COPY_FROM\", -1L );\n        long id_jobentry_copy_to = r.getInteger( \"ID_JOBENTRY_COPY_TO\", -1L );\n\n        jobHopMeta.setEnabled( r.getBoolean( \"ENABLED\", true ) );\n        jobHopMeta.setEvaluation( r.getBoolean( \"EVALUATION\", true ) );\n        jobHopMeta.setConditional();\n        if ( r.getBoolean( \"UNCONDITIONAL\", !jobHopMeta.getEvaluation() ) ) {\n          jobHopMeta.setUnconditional();\n        }\n\n        jobHopMeta.setFromEntry( JobMeta.findJobEntryCopy( jobcopies, new LongObjectId( id_jobentry_copy_from ) ) );\n        jobHopMeta.setToEntry( JobMeta.findJobEntryCopy( jobcopies, new LongObjectId( id_jobentry_copy_to ) ) );\n\n        return jobHopMeta;\n      } else {\n        throw new KettleException( \"Unable to find job hop with ID : \" + id_job_hop );\n      }\n    } catch ( KettleDatabaseException dbe ) {\n      throw new KettleException( BaseMessages.getString( PKG, \"JobHopMeta.Exception.UnableToLoadHopInfoRep\", \"\"\n        + id_job_hop ), dbe );\n\n    }\n  }\n\n  public void saveJobHopMeta( JobHopMeta hop, ObjectId id_job ) throws KettleException {\n    try {\n      ObjectId id_jobentry_from = null;\n      ObjectId id_jobentry_to = null;\n\n      id_jobentry_from = hop.getFromEntry() == null ? null : hop.getFromEntry().getObjectId();\n      id_jobentry_to = hop.getToEntry() == null ? null : hop.getToEntry().getObjectId();\n\n      // Insert new job hop in repository\n      //\n      hop.setObjectId( insertJobHop( id_job, id_jobentry_from, id_jobentry_to, hop.isEnabled(), hop\n        .getEvaluation(), hop.isUnconditional() ) );\n    } catch ( KettleDatabaseException dbe ) {","sourceCodeStart":636,"sourceCodeEnd":672,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/repository/kdr/delegates/KettleDatabaseRepositoryJobDelegate.java#L636-L672","documentation":"Thrown by loadJobHopMeta when a KettleDatabaseException occurs while reading hop information (r_jobhop row and its referenced job entry copies) from the repository. The localized message 'UnableToLoadHopInfoRep' with the hop ID wraps the database cause. Unlike error 1053 this is a read/query failure, not an empty result.","triggerScenarios":"Calling repository.loadJobHopMeta(id) when the SQL select on r_jobhop (or resolving id_jobentry_copy_from/to via findJobEntryCopy) throws — broken connection, SQL syntax/schema mismatch, or dangling references to deleted job entry copies causing lookup failures.","commonSituations":"Orphaned hop rows whose from/to job entries were deleted (violating expected joins); repository schema drift between client and DB versions; connection failure mid-load; DB permission problems reading r_jobhop.","solutions":["Check the wrapped cause (e.getCause()) for the concrete KettleDatabaseException and address the DB issue.","Verify the hop's referenced job entry copies still exist in r_jobentry; delete dangling hop rows if entries are gone.","Align repository schema version with the client (run upgrade/repair scripts).","Reconnect/retry if the failure was a transient connection drop during load."],"exampleFix":"// before: ignoring the wrapped cause\n} catch (KettleException e) {\n  log.warn(e.getMessage());\n}\n\n// after: log cause chain to identify the SQL problem\n} catch (KettleException e) {\n  log.warn(\"Hop load failed: \" + e.getMessage(), e.getCause());\n}","handlingStrategy":"try-catch","validationCode":"// check referenced entries exist before loading the hop\nboolean entriesExist =\n  repo.connectionDelegate.countNonZero(\n    \"SELECT COUNT(*) FROM R_JOBENTRY WHERE ID_JOBENTRY IN (?, ?)\",\n    Arrays.asList(idFrom, idTo)) == 2;\nif (!entriesExist) throw new IllegalStateException(\"Hop references deleted job entries\");","typeGuard":"boolean isLoadableHop(ObjectId hopId) {\n  return hopId != null && hopId.getId() != null && ((Number) hopId.getId()).longValue() > 0;\n}","tryCatchPattern":"try {\n  hop = repo.loadJobHopMeta(hopId);\n} catch (KettleException e) {\n  Throwable root = e;\n  while (root.getCause() != null) root = root.getCause();\n  if (root instanceof KettleDatabaseException && isTransient(root)) {\n    repo.connect(); hop = repo.loadJobHopMeta(hopId); // retry after reconnect\n  } else {\n    throw e; // schema drift / dangling references need repair, not retry\n  }\n}","preventionTips":["Keep client and repository schema versions aligned to avoid SQL/schema mismatches.","Delete hop rows when their job entries are removed to prevent broken references.","Unwrap e.getCause() to see the KettleDatabaseException before deciding on retry vs repair.","Monitor DB connectivity (timeouts, permission errors) in long-running spoon/scheduler sessions."],"tags":["database","repository","job-hop","read-failed"],"backgroundTag":"database-query-failed","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}