{"record":{"id":"70df557ab721cd52","repo":"github/copilot-sdk","slug":"tcpconnectiontoken-must-be-a-non-empty-string","errorCode":null,"errorMessage":"TcpConnectionToken must be a non-empty string","messagePattern":"TcpConnectionToken must be a non-empty string","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"java/sdk/src/main/java/com/github/copilot/CopilotClient.java","lineNumber":194,"sourceCode":"        }\n\n        // Validate mutually exclusive options: cliUrl and cliPath cannot both be set\n        if (this.options.getCliUrl() != null && !this.options.getCliUrl().isEmpty()\n                && this.options.getCliPath() != null) {\n            throw new IllegalArgumentException(\"CliUrl is mutually exclusive with CliPath\");\n        }\n\n        // Validate auth options with external server\n        if (this.options.getCliUrl() != null && !this.options.getCliUrl().isEmpty()\n                && (this.options.getGitHubToken() != null || this.options.getUseLoggedInUser().isPresent())) {\n            throw new IllegalArgumentException(\n                    \"GitHubToken and UseLoggedInUser cannot be used with CliUrl (external server manages its own auth)\");\n        }\n\n        // Validate tcpConnectionToken\n        if (this.options.getTcpConnectionToken() != null) {\n            if (this.options.getTcpConnectionToken().isEmpty()) {\n                throw new IllegalArgumentException(\"TcpConnectionToken must be a non-empty string\");\n            }\n            if (this.options.isUseStdio()) {\n                throw new IllegalArgumentException(\"TcpConnectionToken cannot be used with UseStdio = true\");\n            }\n        }\n\n        // Compute effective connection token: use provided, or auto-generate for\n        // SDK-spawned TCP mode, or null for stdio/external server\n        boolean sdkSpawnsCli = !this.options.isUseStdio()\n                && (this.options.getCliUrl() == null || this.options.getCliUrl().isEmpty());\n        this.effectiveConnectionToken = this.options.getTcpConnectionToken() != null\n                ? this.options.getTcpConnectionToken()\n                : (sdkSpawnsCli ? java.util.UUID.randomUUID().toString() : null);\n\n        // Empty mode: validate at construction time that the app supplied a\n        // per-session persistence location.\n        if (this.options.getMode() == CopilotClientMode.EMPTY) {\n            boolean hasPersistence = (this.options.getCopilotHome() != null && !this.options.getCopilotHome().isEmpty())","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/java/sdk/src/main/java/com/github/copilot/CopilotClient.java#L176-L212","documentation":"CopilotClient validates at construction that the tcpConnectionToken option, when provided, is a non-empty string. An empty string is treated as an invalid configuration rather than 'not provided', so the constructor throws IllegalArgumentException immediately. Set the option to null to omit it instead of passing \"\".","triggerScenarios":"new CopilotClient(...) with CopilotClientOptions where setTcpConnectionToken(\"\") or an options object built from an empty/blank config value or environment variable was used while isUseStdio() handling requires a real token.","commonSituations":"Reading the token from an env var or properties file that exists but is empty; string interpolation producing \"\"; default-initializing the option to \"\" instead of null.","solutions":["Pass null instead of \"\" when you have no TCP connection token","Supply the actual token generated by the SDK or your TCP server","Trim the config/env value and treat blank as absent before calling setTcpConnectionToken"],"exampleFix":"// before\noptions.setTcpConnectionToken(\"\");\n// after\nString token = System.getenv(\"COPILOT_TCP_TOKEN\");\nif (token != null && !token.isBlank()) options.setTcpConnectionToken(token.trim());","handlingStrategy":"validation","validationCode":"if (token != null && token.isEmpty()) throw new IllegalArgumentException(\"tcpConnectionToken must be empty or absent\");","typeGuard":"boolean isValidTcpToken(String t) { return t == null || !t.isEmpty(); }","tryCatchPattern":"try { new CopilotClient(options); } catch (IllegalArgumentException e) { if (e.getMessage().contains(\"TcpConnectionToken\")) { /* fix options */ } else throw e; }","preventionTips":["Treat blank config values as absent (use null, not \"\")","Trim env/config values before setting the token","Unit-test options construction with all transports"],"tags":["java","configuration","validation","tcp"],"backgroundTag":"empty-required-field","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}