{"record":{"id":"63daeaf26c6c9d10","repo":"pentaho/pentaho-kettle","slug":"pentaho-messages-bundle-path-argument-is-invalid-bundlepath-63daea","errorCode":null,"errorMessage":"[pentaho/messages!] Bundle path argument is invalid: '${bundlePath}'.","messagePattern":"\\[pentaho/messages!\\] Bundle path argument is invalid: '(.+?)'\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"plugins/core-ui/src/main/resources/app/pentaho/i18n.js","lineNumber":124,"sourceCode":"    // bundlePath: pentaho/common/nls/messages\n    // bundleMid:  pentaho/common/nls/messages\n    // absBundleUrl: /pentaho/content/common-ui/resources/web/dojo/pentaho/common/nls/messages\n    // basePath: /pentaho/\n    // pluginId: common-ui\n    // bundleName: resources/web/dojo/pentaho/common/nls/messages\n\n    var bundleMid = __getBundleId(bundlePath);\n    var bundleUrlPath = __getBundleUrlPath(localRequire, bundleMid);\n\n    // Split the url into pluginId and bundleName\n    // \"pluginId/...bundleName...\"\n    var separatorIndex = bundleUrlPath.indexOf(\"/\");\n\n    // Catch invalid bundle url paths and throw when\n    // the bundleUrlPath 1) starts or 2) ends with a forward slash (/)\n    var isValidBundleUrlPath = separatorIndex > 0 || separatorIndex < bundleUrlPath.length - 1;\n    if (!isValidBundleUrlPath) {\n      throw new Error(\"[pentaho/messages!] Bundle path argument is invalid: '\" + bundlePath + \"'.\");\n    }\n\n    return {\n      pluginId: bundleUrlPath.substr(0, separatorIndex),\n      name: bundleUrlPath.substr(separatorIndex + 1)\n    };\n  }\n\n  function __getBundleUrlPath(localRequire, bundleMid) {\n    var SERVER_ROOT_PATH = env.server.root.pathname;\n    var CONTENT_PATH = \"content/\";\n    var PLUGIN_PATH = \"/plugin/\";\n    var CGG_URL_SCHEME = \"res:\";\n\n    var bundleUrl = url.create(localRequire.toUrl(bundleMid));\n    var bundleUrlPath = bundleUrl.pathname;\n    var bundleUrlScheme = bundleUrl.protocol;\n","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/core-ui/src/main/resources/app/pentaho/i18n.js#L106-L142","documentation":"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.","triggerScenarios":"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'.","commonSituations":"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.","solutions":["Trim leading/trailing slashes from the path before calling.","Ensure the path is '<pluginId>/<bundleName>' with non-empty segments around the first '/'.","Prefer the documented forms: bare bundle name, './i18n/<name>', or 'pentaho/i18n!<absolute-module-id>'.","Wrap dynamic path construction in a validator that checks indexOf('/') is between 1 and length-2.","Correct the configured bundle path in require config or i18n call sites."],"exampleFix":"// before\nbundleInfo(\"pentaho/common/nls/messages/\"); // trailing slash -> throw\n// after\nbundleInfo(\"pentaho/common/nls/messages\");","handlingStrategy":"validation","validationCode":"function checkBundlePath(p) {\n  var sep = String(p).indexOf(\"/\");\n  if (!(sep > 0 && sep < String(p).length - 1)) {\n    throw new Error(\"bundlePath must be '<pluginId>/<bundleName>': \" + p);\n  }\n}\ncheckBundlePath(bundlePath);\nbundleInfo(bundlePath);","typeGuard":"function isPluginBundlePath(v) {\n  return typeof v === \"string\" && /^[^/]+\\/[^/].*$/.test(v) && v.slice(-1) !== \"/\";\n}","tryCatchPattern":"try {\n  return bundleInfo(bundlePath);\n} catch (e) {\n  if (String(e.message).indexOf(\"Bundle path argument is invalid\") !== -1) {\n    var cleaned = String(bundlePath).replace(/^\\/+|\\/+$/g, \"\");\n    return bundleInfo(cleaned);\n  }\n  throw e;\n}","preventionTips":["Centralize bundle-path construction in one utility that sanitizes slashes.","Add startup-time assertions on all i18n paths from configuration.","Cover leading/trailing-slash cases in unit tests for path builders.","Use module ids (no leading slash) when targeting 'pentaho/i18n!'."],"tags":["i18n","path-validation","argument-validation"],"backgroundTag":"invalid-argument-value","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"}