pentaho/pentaho-kettle · error · Error

[pentaho/messages!] Bundle path argument is invalid

Error message

[pentaho/messages!] Bundle path argument is invalid: '{bundlePath}'.

What it means

The pentaho/i18n message-bundle service resolves a bundle path like 'pluginId/bundleName' into a plugin id and bundle name by splitting the derived bundleUrlPath on the first '/'. __getBundleInfo throws this error when the path is structurally invalid — the separator is missing, at index 0 (leading slash), or at the last position (trailing slash) — because no valid pluginId/bundleName pair can be extracted. It guards against malformed module ids reaching the AMD loader as bundle locations.

Solutions

  1. Log and inspect the bundlePath argument before the i18n call; trim leading/trailing slashes.
  2. Ensure the path has the form '<pluginId>/<bundleName>' with a non-empty part on both sides of the first '/'.
  3. Use relative forms ('./i18n/messages' or a bare bundle name) supported by the i18n module instead of absolute slashed paths.
  4. Add a small normalizer (strip, split, validate both segments non-empty) before passing any dynamic path.
  5. If the path comes from configuration, fix the config value to a valid plugin-relative bundle id.

Example fix

// before
i18n(bundlePath + "/i18n/messages"); // bundlePath='/pentaho' -> '/pentaho/i18n/messages' invalid
// after
var clean = bundlePath.replace(/^\/+|\/+$/g, "");
i18n(clean + "/i18n/messages"); // 'pentaho/i18n/messages'
Defensive patterns

Strategy: validation

Validate before calling

function isValidBundlePath(p) {
  if (typeof p !== "string" || p.length === 0) return false;
  var i = p.indexOf("/");
  return i > 0 && i < p.length - 1;
}
if (!isValidBundlePath(bundlePath)) throw new Error("Bad bundlePath: " + bundlePath);

Type guard

function isBundlePath(v) {
  return typeof v === "string" && v.indexOf("/") > 0 && v.indexOf("/") < v.length - 1;
}

Try / catch

try {
  i18n(bundlePath);
} catch (e) {
  if (String(e.message).indexOf("Bundle path argument is invalid") !== -1) {
    bundlePath = bundlePath.replace(/^\/+|\/+$/g, "");
    return i18n(bundlePath);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling i18n bundle APIs with a bundlePath such as '/foo' (starts with '/'), 'foo/' (ends with '/'), '/' alone, or a string containing no '/' so that separatorIndex is -1, making isValidBundleUrlPath false.

Common situations: Typo'd or hand-built bundle paths in requirejs config or i18n! calls; concatenating strings that leave a trailing slash; refactoring a module path like 'pentaho/common/nls/messages' into 'pentaho/common/nls/messages/' after copy/paste; empty plugin id after normalization.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at plugins/core-ui/src/main/resources/app/pentaho/i18n/serverService.js:124

    // bundlePath: pentaho/common/nls/messages
    // bundleMid:  pentaho/common/nls/messages
    // absBundleUrl: /pentaho/content/common-ui/resources/web/dojo/pentaho/common/nls/messages
    // basePath: /pentaho/
    // pluginId: common-ui
    // bundleName: resources/web/dojo/pentaho/common/nls/messages

    var bundleMid = __getBundleId(bundlePath);
    var bundleUrlPath = __getBundleUrlPath(localRequire, bundleMid);

    // Split the url into pluginId and bundleName
    // "pluginId/...bundleName..."
    var separatorIndex = bundleUrlPath.indexOf("/");

    // Catch invalid bundle url paths and throw when
    // the bundleUrlPath 1) starts or 2) ends with a forward slash (/)
    var isValidBundleUrlPath = separatorIndex > 0 || separatorIndex < bundleUrlPath.length - 1;
    if(!isValidBundleUrlPath) {
      throw new Error("[pentaho/messages!] Bundle path argument is invalid: '" + bundlePath + "'.");
    }

    return {
      pluginId: bundleUrlPath.substr(0, separatorIndex),
      name: bundleUrlPath.substr(separatorIndex + 1)
    };
  }

  function __getBundleUrlPath(localRequire, bundleMid) {
    var SERVER_ROOT_PATH = environment.server.root.pathname;
    var CONTENT_PATH = "content/";
    var PLUGIN_PATH = "/plugin/";
    var CGG_URL_SCHEME = "res:";

    var bundleUrl = url.create(localRequire.toUrl(bundleMid));
    var bundleUrlPath = bundleUrl.pathname;
    var bundleUrlScheme = bundleUrl.protocol;

View on GitHub (pinned to f3058517a1)