{"record":{"id":"5259c684c0817eda","repo":"pentaho/pentaho-kettle","slug":"pentaho-messages-bundle-path-argument-is-invalid-bundlepath","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/serverService.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 = environment.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/serverService.js#L106-L142","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Log and inspect the bundlePath argument before the i18n call; trim leading/trailing slashes.","Ensure the path has the form '<pluginId>/<bundleName>' with a non-empty part on both sides of the first '/'.","Use relative forms ('./i18n/messages' or a bare bundle name) supported by the i18n module instead of absolute slashed paths.","Add a small normalizer (strip, split, validate both segments non-empty) before passing any dynamic path.","If the path comes from configuration, fix the config value to a valid plugin-relative bundle id."],"exampleFix":"// before\ni18n(bundlePath + \"/i18n/messages\"); // bundlePath='/pentaho' -> '/pentaho/i18n/messages' invalid\n// after\nvar clean = bundlePath.replace(/^\\/+|\\/+$/g, \"\");\ni18n(clean + \"/i18n/messages\"); // 'pentaho/i18n/messages'","handlingStrategy":"validation","validationCode":"function isValidBundlePath(p) {\n  if (typeof p !== \"string\" || p.length === 0) return false;\n  var i = p.indexOf(\"/\");\n  return i > 0 && i < p.length - 1;\n}\nif (!isValidBundlePath(bundlePath)) throw new Error(\"Bad bundlePath: \" + bundlePath);","typeGuard":"function isBundlePath(v) {\n  return typeof v === \"string\" && v.indexOf(\"/\") > 0 && v.indexOf(\"/\") < v.length - 1;\n}","tryCatchPattern":"try {\n  i18n(bundlePath);\n} catch (e) {\n  if (String(e.message).indexOf(\"Bundle path argument is invalid\") !== -1) {\n    bundlePath = bundlePath.replace(/^\\/+|\\/+$/g, \"\");\n    return i18n(bundlePath);\n  }\n  throw e;\n}","preventionTips":["Normalize paths: strip leading/trailing slashes once in a helper used by all i18n call sites.","Use the documented relative forms ('./i18n/messages', bare names) instead of hand-built absolute ids.","Validate configured bundle paths at startup, not at first use.","Add a unit test covering '/', '/x', 'x/', and '' for your path builder."],"tags":["i18n","path-validation","argument-validation","amd-loader"],"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"}