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

Duplicate implementation of the i18n bundle-path parsing found in pentaho/i18n.js: __getBundleInfo splits bundleUrlPath on the first '/' to derive {pluginId, name} and throws when the path is invalid — no separator, a leading slash, or a trailing slash — since a valid pluginId/bundleName pair cannot be formed. This is the same contract as the serverService.js variant, living in the client-side i18n module.

Solutions

  1. Trim leading/trailing slashes from the path before calling.
  2. Ensure the path is '<pluginId>/<bundleName>' with non-empty segments around the first '/'.
  3. Prefer the documented forms: bare bundle name, './i18n/<name>', or 'pentaho/i18n!<absolute-module-id>'.
  4. Wrap dynamic path construction in a validator that checks indexOf('/') is between 1 and length-2.
  5. Correct the configured bundle path in require config or i18n call sites.

Example fix

// before
bundleInfo("pentaho/common/nls/messages/"); // trailing slash -> throw
// after
bundleInfo("pentaho/common/nls/messages");
Defensive patterns

Strategy: validation

Validate before calling

function checkBundlePath(p) {
  var sep = String(p).indexOf("/");
  if (!(sep > 0 && sep < String(p).length - 1)) {
    throw new Error("bundlePath must be '<pluginId>/<bundleName>': " + p);
  }
}
checkBundlePath(bundlePath);
bundleInfo(bundlePath);

Type guard

function isPluginBundlePath(v) {
  return typeof v === "string" && /^[^/]+\/[^/].*$/.test(v) && v.slice(-1) !== "/";
}

Try / catch

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

Prevention

When it happens

Trigger: Calling bundleInfo (and downstream i18n APIs) with a bundlePath whose derived url path starts or ends with '/', contains no '/', or is empty/'/'; e.g. '/common/nls/messages', 'common/nls/messages/', or 'messages'.

Common situations: Copy-pasted absolute paths that kept a leading slash; string concatenation leaving a trailing slash; calling with a bare bundle name (no slash) which is only valid for the __getBundleId fast-path, not this absolute-path branch; refactors that changed module id depth.

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/63daeaf26c6c9d10. Report an issue: GitHub.

Appendix: source

Thrown at plugins/core-ui/src/main/resources/app/pentaho/i18n.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 = env.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)