{"record":{"id":"accbffaaad3a9348","repo":"apache/seatunnel","slug":"option-option-cannot-be-blank-accbff","errorCode":null,"errorMessage":"Option '${option}' cannot be blank","messagePattern":"Option '(.+?)' cannot be blank","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-google-pubsub/src/main/java/org/apache/seatunnel/connectors/seatunnel/google/pubsub/config/GooglePubSubSinkConfig.java","lineNumber":70,"sourceCode":"                    \"Options 'credentials_path' and 'emulator_host' cannot be configured together\");\n        }\n        if (format == MessageFormat.TEXT && fieldDelimiter.isEmpty()) {\n            throw new IllegalArgumentException(\"Option 'field_delimiter' cannot be empty\");\n        }\n\n        return GooglePubSubSinkConfig.builder()\n                .projectId(projectId)\n                .topic(topic)\n                .credentialsPath(credentialsPath)\n                .emulatorHost(emulatorHost)\n                .format(format)\n                .fieldDelimiter(fieldDelimiter)\n                .build();\n    }\n\n    private static void requireNonBlank(String value, String option) {\n        if (value == null || value.trim().isEmpty()) {\n            throw new IllegalArgumentException(\"Option '\" + option + \"' cannot be blank\");\n        }\n    }\n\n    private static void requireNonBlankIfPresent(String value, String option) {\n        if (value != null) {\n            requireNonBlank(value, option);\n        }\n    }\n}\n","sourceCodeStart":52,"sourceCodeEnd":80,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-google-pubsub/src/main/java/org/apache/seatunnel/connectors/seatunnel/google/pubsub/config/GooglePubSubSinkConfig.java#L52-L80","documentation":"requireNonBlank() is the shared validator in GooglePubSubSinkConfig that rejects null, empty, or whitespace-only values for mandatory options (projectId, topic, and conditionally credentials_path/emulator_host). It throws IllegalArgumentException naming the offending option key, so blank required options fail fast at sink construction.","triggerScenarios":"from() calls requireNonBlank (directly or via requireNonBlankIfPresent with a non-null value) and the value is null, \"\", or whitespace — e.g. project_id missing, topic = \"\", or credentials_path = \" \" present but blank.","commonSituations":"Environment variable placeholders (topic = \"${TOPIC}\") left unset so they resolve to empty/whitespace; copying a config and deleting the value but keeping the key with empty string; quoting errors producing a blank string.","solutions":["Set the named option (see the message: Option 'X' cannot be blank) to a non-blank value.","If the value comes from an environment variable, export it before job submission or give it a default.","Remove the option entirely if it is optional (requireNonBlankIfPresent only validates when present)."],"exampleFix":"// before\ntopic = \"${PUBSUB_TOPIC}\"  # env var not set\n// after\ntopic = \"my-topic\"  # or: export PUBSUB_TOPIC=my-topic","handlingStrategy":"validation","validationCode":"// pre-flight check of required options\nList<String> required = List.of(\"project_id\", \"topic\");\nfor (String key : required) {\n  String v = config.getString(key);\n  if (v == null || v.trim().isEmpty()) throw new IllegalArgumentException(\"Option '\" + key + \"' must be non-blank\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  GooglePubSubSinkConfig.from(config);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"cannot be blank\")) {\n    log.error(\"Provide a value for the option named in: {}\", e.getMessage());\n  } else throw e;\n}","preventionTips":["Export all env vars referenced via ${...} placeholders before running the job.","Validate config completeness in CI with a schema/keys check.","Avoid keeping keys with empty-string values; omit optional keys entirely."],"tags":["pubsub","config","validation","required-field"],"backgroundTag":"missing-required-config-field","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}