{"record":{"id":"a8054132d1f994fc","repo":"pentaho/pentaho-kettle","slug":"key-must-not-start-with","errorCode":null,"errorMessage":"Key must not start with '-'","messagePattern":"Key must not start with '-'","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/core/util/KeyValue.java","lineNumber":93,"sourceCode":"   */\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;\n  }\n\n  /**\n   * @return the value","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/core/util/KeyValue.java#L75-L111","documentation":"KeyValue.assertKey() rejects keys that begin with '-' to prevent them from being mistaken for command-line flags or negative-prefixed identifiers. A leading hyphen triggers IllegalArgumentException('Key must not start with \\'-\\'').","triggerScenarios":"Constructing a KeyValue (or calling assertKey) with a key like '-verbose' or '--force', e.g. when mapping CLI flag names directly to keys.","commonSituations":"Developers reusing CLI option names as key names; string manipulations that leave a leading dash after sanitizing.","solutions":["Strip leading '-' characters from the key before creating the KeyValue.","Rename the key without the leading hyphen (e.g. 'verbose' instead of '-verbose').","Apply the same lowercase/replace sanitize step used for invalid characters, trimming leading hyphens first."],"exampleFix":"// before\nnew KeyValue<>(\"-verbose\", true);\n// after\nString key = \"-verbose\".replaceAll(\"^-+\", \"\");\nnew KeyValue<>(key, true); // \"verbose\"","handlingStrategy":"validation","validationCode":"if (key.startsWith(\"-\")) {\n  throw new IllegalArgumentException(\"Key must not start with '-': \" + key);\n}","typeGuard":null,"tryCatchPattern":"try {\n  new KeyValue<>(key, value);\n} catch (IllegalArgumentException e) {\n  key = key.replaceAll(\"^-+\", \"\"); // strip and retry once\n}","preventionTips":["Strip leading hyphens when deriving keys from CLI flag names.","Trim '-' in the shared key-normalization helper (replaceAll(\"^-+\", \"\")).","Prefer semantic names over flag-style identifiers for keys."],"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"}