{"record":{"id":"b063d0b94cd7b8a2","repo":"pentaho/pentaho-kettle","slug":"key-contains-invalid-characters-validkeycharacters-valid-key","errorCode":null,"errorMessage":"Key contains invalid characters [validKeyCharacters=${VALID_KEY_CHARS}]","messagePattern":"Key contains invalid characters \\[validKeyCharacters=(.+?)\\]","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/core/util/KeyValue.java","lineNumber":89,"sourceCode":"   * @param key\n   *          key to set.\n   * @throws IllegalArgumentException\n   *           if key is invalid.\n   */\n  public KeyValue( final String key ) throws IllegalArgumentException {\n    this( key, null );\n  }\n\n  /**\n   * @param lowerKey\n   *          key to test.\n   * @throws IllegalArgumentException\n   *           if key is invalid.\n   */\n  public static final void assertKey( final String lowerKey ) throws IllegalArgumentException {\n    Assert.assertNotEmpty( lowerKey, \"Key cannot be null or empty\" );\n    if ( !StringUtils.containsOnly( lowerKey, VALID_KEY_CHARS ) ) {\n      throw new IllegalArgumentException( \"Key contains invalid characters [validKeyCharacters=\"\n        + VALID_KEY_CHARS + \"]\" );\n    }\n    if ( lowerKey.charAt( 0 ) == '-' ) {\n      throw new IllegalArgumentException( \"Key must not start with '-'\" );\n    }\n    if ( lowerKey.endsWith( \"-\" ) ) {\n      throw new IllegalArgumentException( \"Key must not end with '-'\" );\n    }\n    if ( \"_\".equals( lowerKey ) ) {\n      throw new IllegalArgumentException( \"Key must not be  '_'\" );\n    }\n  }\n\n  /**\n   * @return the key, never null.\n   */\n  public String getKey() {\n    return this.key;","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/core/util/KeyValue.java#L71-L107","documentation":"KeyValue.assertKey() validates that a key is non-empty and consists only of VALID_KEY_CHARS (lowercase alphanumerics, underscore, hyphen). If StringUtils.containsOnly fails, it throws IllegalArgumentException with the list of valid characters. This keeps keys usable in environments like env-var/CLI/JSON contexts.","triggerScenarios":"Calling new KeyValue<>(key, value) (or assertKey directly) with a key containing spaces, uppercase letters, dots, slashes, or other characters outside the allowed set.","commonSituations":"Passing human-readable labels as keys ('Max Retries'); keys copied from config files with dots ('a.b.c'); camelCase keys not lowercased before validation.","solutions":["Sanitize the key to lowercase and replace invalid characters with '-' or '_' before constructing the KeyValue.","Use only [a-z0-9_-] characters in keys.","Call KeyValue.assertKey(key) proactively in your own code to fail early with your own message."],"exampleFix":"// before\nnew KeyValue<>(\"Max Retries\", 3);\n// after\nString key = \"Max Retries\".toLowerCase().replaceAll(\"[^a-z0-9_-]\", \"-\");\nnew KeyValue<>(key, 3); // \"max-retries\"","handlingStrategy":"validation","validationCode":"if (key == null || key.isEmpty() || !key.matches(\"[a-z0-9_-]+\")) {\n  throw new IllegalArgumentException(\"Invalid key: \" + key);\n}","typeGuard":null,"tryCatchPattern":"try {\n  KeyValue.assertKey(key);\n} catch (IllegalArgumentException e) {\n  throw new IllegalArgumentException(\"Sanitize key before use: '\" + key + \"'\", e);\n}","preventionTips":["Run all keys through a single normalize (lowercase, replace [^a-z0-9_-]) helper.","Never pass display labels or dotted config paths directly as keys.","Call assertKey early in your pipeline to fail with context."],"tags":["validation","key-format","illegal-argument"],"backgroundTag":"invalid-identifier-format","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"}