{"record":{"id":"45f6feef1698f13e","repo":"apache/pulsar","slug":"cannot-parse-source-config","errorCode":null,"errorMessage":"Cannot parse source-config","messagePattern":"Cannot parse source-config","errorType":"validation","errorClass":"ParameterException","httpStatus":null,"severity":"error","filePath":"pulsar-client-tools/src/main/java/org/apache/pulsar/admin/cli/CmdSources.java","lineNumber":486,"sourceCode":"                resources.setRam(ram);\n            }\n\n            if (disk != null) {\n                if (resources == null) {\n                    resources = new Resources();\n                }\n                resources.setDisk(disk);\n            }\n            if (resources != null) {\n                sourceConfig.setResources(resources);\n            }\n\n            try {\n                if (null != sourceConfigString) {\n                    sourceConfig.setConfigs(parseConfigs(sourceConfigString));\n                }\n            } catch (Exception ex) {\n                throw new ParameterException(\"Cannot parse source-config\", ex);\n            }\n\n            if (null != batchSourceConfigString) {\n                sourceConfig.setBatchSourceConfig(parseBatchSourceConfigs(batchSourceConfigString));\n            }\n\n            if (customRuntimeOptions != null) {\n                sourceConfig.setCustomRuntimeOptions(customRuntimeOptions);\n            }\n\n            if (secretsString != null) {\n                Type type = new TypeToken<Map<String, Object>>() {}.getType();\n                Map<String, Object> secretsMap = new Gson().fromJson(secretsString, type);\n                if (secretsMap == null) {\n                    secretsMap = Collections.emptyMap();\n                }\n                sourceConfig.setSecrets(secretsMap);\n            }","sourceCodeStart":468,"sourceCodeEnd":504,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client-tools/src/main/java/org/apache/pulsar/admin/cli/CmdSources.java#L468-L504","documentation":"CmdSources.processArguments failed while parsing the --source-config YAML/JSON string into a config map; the string is malformed, so it cannot be applied to the SourceConfig and a ParameterException wraps the cause.","triggerScenarios":"Passing `--source-config` with invalid JSON such as `key=value` pairs, YAML text, or JSON broken by shell quote stripping, e.g. `--source-config '{bootstrap.servers: localhost}'`.","commonSituations":"Bash removing inner double quotes so the JSON becomes invalid; using a properties-style string instead of a JSON object; trailing commas.","solutions":["Fix the source-config string to be valid JSON/YAML","Quote the argument properly in the shell"],"exampleFix":"// before\n--source-config 'bootstrap.servers=localhost:9092'\n// after\n--source-config '{\"bootstrap.servers\":\"localhost:9092\"}'","handlingStrategy":"validation","validationCode":"const cfg = JSON.parse(sourceConfigString); // throws before invoking CLI if malformed\nif (typeof cfg !== 'object' || Array.isArray(cfg)) throw new Error('source-config must be a JSON object');","typeGuard":"const isJsonObject = (s) => { try { return !Array.isArray(JSON.parse(s)) && typeof JSON.parse(s) === 'object'; } catch { return false; } };","tryCatchPattern":"try {\n  // run sources create with --source-config\n} catch (e) {\n  if (e.message.includes('Cannot parse source-config')) { /* switch to --source-config-file */ }\n  throw e;\n}","preventionTips":["Use valid JSON with quoted keys for --source-config","Prefer --source-config-file over inline strings","Validate with `jq .` before running the CLI"],"tags":["cli","json","configuration"],"backgroundTag":"invalid-json-config","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}