pentaho/pentaho-kettle · error · RepositoryClientException

status:

Error message

 status:

What it means

RepositoryClient.throwOnError reads the HTTP error body from a Pentaho repository REST response and wraps it in a RepositoryClientException containing the raw body plus the status code (e.g. '... status:404'). It is thrown whenever the repo-vfs web-service client receives a non-success HTTP response on writeData, moveTo, rename, or getFileInfo. It signals that the server rejected the repository operation at the HTTP level.

Solutions

  1. Read the status code and body in the exception message and address the underlying HTTP cause (401 => re-authenticate/reconnect the repository; 404 => refresh the VFS cache and re-check file existence)
  2. Reconnect to the repository if the status indicates an expired session (401/403) and retry the operation
  3. Check whether another client moved/deleted the target file; refresh the file object before retrying
  4. Verify repository base URL and network/proxy configuration if the body is empty or unparseable

Example fix

// before
client.getFileInfo( path ); // may throw RepositoryClientException '... status:404'
// after
try {
  client.getFileInfo( path );
} catch ( RepositoryClientException e ) {
  if ( e.getMessage() != null && e.getMessage().endsWith( "status:404" ) ) {
    fileObject.refresh(); // re-check existence before proceeding
  } else {
    throw e;
  }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// before the call
if ( !fileObject.exists() ) { fileObject.refresh(); if ( !fileObject.exists() ) return; }
if ( repository == null || !repository.isConnected() ) { reconnectRepository(); }

Type guard

boolean isHttpStatusFailure( RepositoryClientException e ) {
  String m = e.getMessage();
  return m != null && m.matches( ".* status:\\d{3}$" );
}

Try / catch

try {
  client.writeData( name, data );
} catch ( RepositoryClientException e ) {
  if ( e.getMessage() != null && e.getMessage().endsWith( "status:401" ) ) {
    reconnectAndRetry();
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Calling writeData, moveTo, rename, or getFileInfo via RepositoryClient when the server returns a non-2xx status (401 unauthenticated, 404 file not found, 409 conflict, 500 server error). Common when the repository path was deleted or renamed by another client between calls, or when the session cookie expired.

Common situations: Expired JCR session mid-operation; two Spoon instances editing the same file causing 409 on moveTo/rename; proxy or firewall returning HTML error pages that fail readEntity and yield 'Unable to get error response entity'; wrong repository base URL.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/22e600d4523e5f4d. Report an issue: GitHub.

Appendix: source

Thrown at plugins/repo-vfs/repo-vfs-ws/src/main/java/org/pentaho/di/plugins/repovfs/ws/repo/RepositoryClient.java:289

    return ":" + Stream.of( path ).map( Encode::forUriComponent ).collect( Collectors.joining( ":" ) );
  }

  private void throwOnError( final Response response ) throws RepositoryClientException {
    final int status = response.getStatus();

    if ( status != HttpStatus.SC_OK ) {
      if ( status == HttpStatus.SC_MOVED_TEMPORARILY
        || status == HttpStatus.SC_FORBIDDEN
        || status == HttpStatus.SC_UNAUTHORIZED ) {
        throw new RepositoryClientException( "Auth error" );
      } else {
        String errMsg;
        try {
          errMsg = response.readEntity( String.class );
        } catch ( Exception e ) {
          errMsg = "Unable to get error response entity";
        }
        throw new RepositoryClientException( errMsg + " status:" + status );
      }
    }
  }

  private static String encodePath( String path ) {
    String repoEncoded = RepositoryPathEncoder.encodeRepositoryPath( path );
    return Encode.forUriComponent( repoEncoded );
  }
}

View on GitHub (pinned to f3058517a1)