{"record":{"id":"cec906b9288229d2","repo":"apache/beam","slug":"secret-option-string-cannot-be-null","errorCode":null,"errorMessage":"Secret option string cannot be null","messagePattern":"Secret option string cannot be null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/util/Secret.java","lineNumber":206,"sourceCode":"  }\n\n  /** Returns secret value as UTF-8 string without caching. */\n  public @Nullable String getString() {\n    return getString(false);\n  }\n\n  /**\n   * Parses a secret string and returns the appropriate secret type.\n   *\n   * <p>The secret string should be formatted like:\n   * 'type:&lt;secret_type&gt;;&lt;secret_param&gt;:&lt;value&gt;'\n   *\n   * <p>For example, 'type:GcpSecret;version_name:my_secret/versions/latest' would return a\n   * GcpSecret initialized with 'my_secret/versions/latest'.\n   */\n  public static Secret parseSecretOption(String secretOption) {\n    if (secretOption == null) {\n      throw new IllegalArgumentException(\"Secret option string cannot be null\");\n    }\n    Map<String, String> paramMap = new HashMap<>();\n    for (String param : secretOption.split(\";\", -1)) {\n      String[] parts = param.split(\":\", 2);\n      if (parts.length == 2) {\n        paramMap.put(parts[0], parts[1]);\n      }\n    }\n\n    if (!paramMap.containsKey(\"type\")) {\n      throw new IllegalArgumentException(\"Secret string must contain a valid type parameter\");\n    }\n\n    String rawType = paramMap.remove(\"type\");\n    if (rawType == null || rawType.isEmpty()) {\n      throw new IllegalArgumentException(\"Secret string must contain a valid type parameter\");\n    }\n","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/util/Secret.java#L188-L224","documentation":"parseSecretOption validates its input before parsing the 'type:key;key=value' style secret option string. Passing null immediately throws IllegalArgumentException because a null option cannot identify any secret. This is a fail-fast guard against misconfigured pipeline options.","triggerScenarios":"Calling Secret.parseSecretOption(null), typically when a pipeline option holding the secret specification was never set.","commonSituations":"A pipeline option like --secretOption is left unset (null default) while the code unconditionally parses it; wiring code passes an unset ValueProvider or null config field into parseSecretOption.","solutions":["Set the secret option in your pipeline launch configuration (e.g. --secretOption=type:GcpSecret;version_name=my_secret/versions/latest).","Null-check the option before calling parseSecretOption and skip or fail with a clearer message.","Give the pipeline option a sensible default or make it @Required so the job fails earlier with a validation error."],"exampleFix":"// before\nSecret secret = Secret.parseSecretOption(options.getSecretOption());\n// after\nString opt = options.getSecretOption();\nSecret secret = opt == null ? null : Secret.parseSecretOption(opt);","handlingStrategy":"type-guard","validationCode":"if (secretOption == null) { throw new IllegalStateException(\"--secretOption must be set\"); }","typeGuard":"if (secretOption != null) { Secret s = Secret.parseSecretOption(secretOption); }","tryCatchPattern":"try { Secret s = Secret.parseSecretOption(opt); } catch (IllegalArgumentException e) { /* handle null/malformed option */ }","preventionTips":["Always set the secret option in pipeline launch configs.","Null-check options before parsing.","Use @Required-style validation on pipeline options so failures surface at startup."],"tags":["java","beam","secrets","configuration","null-check"],"backgroundTag":"null-argument","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}