{"record":{"id":"3a3dad7d07a6d5a2","repo":"conductor-oss/conductor","slug":"token-must-not-be-blank","errorCode":null,"errorMessage":"token must not be blank","messagePattern":"token must not be blank","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"ai/src/main/java/org/conductoross/conductor/ai/agent/credentials/StaticTokenProvider.java","lineNumber":22,"sourceCode":" * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * <p>\n * http://www.apache.org/licenses/LICENSE-2.0\n * <p>\n * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on\n * an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations under the License.\n */\npackage org.conductoross.conductor.ai.agent.credentials;\n\n/** {@link TokenProvider} for non-expiring API keys (OpenAI, Anthropic, etc.). */\npublic class StaticTokenProvider implements TokenProvider {\n\n    private final String token;\n\n    public StaticTokenProvider(String token) {\n        if (token == null || token.isBlank()) {\n            throw new IllegalArgumentException(\"token must not be blank\");\n        }\n        this.token = token;\n    }\n\n    @Override\n    public String getToken() {\n        return token;\n    }\n}\n","sourceCodeStart":4,"sourceCodeEnd":32,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/ai/src/main/java/org/conductoross/conductor/ai/agent/credentials/StaticTokenProvider.java#L4-L32","documentation":"Thrown by the StaticTokenProvider constructor when the token argument is null or blank (String.isBlank). StaticTokenProvider wraps non-expiring API keys (OpenAI, Anthropic, etc.), and a blank key is treated as a programming/config error rather than a recoverable runtime condition. It is an IllegalArgumentException, so it surfaces immediately at bean/wiring time, not at first use.","triggerScenarios":"Constructing new StaticTokenProvider(token) where token came from an environment variable or config property that is unset or empty. Typically fails during Spring bean creation at startup.","commonSituations":"The API key env var (e.g. OPENAI_API_KEY) is not set in the deployment; the property name in YAML does not match what the code reads; a secret manager rotation left the value temporarily empty; a placeholder like ${API_KEY} was left unresolvable.","solutions":["Set the missing API-key environment variable / property to a real, non-blank value.","Verify the property/env name the StaticTokenProvider is built from exactly matches what is configured (typo in @Value(\"${...}\") is common).","Add a startup health check or @PostConstruct assertion that fails fast with a clear message when the key source is empty.","If the key genuinely can be absent in some profile, build a different TokenProvider (or skip the AI integration) conditionally instead of constructing StaticTokenProvider with null."],"exampleFix":"// before\nnew StaticTokenProvider(System.getenv(\"OPENAI_KEY\")) // null if unset\n// after\nString key = System.getenv(\"OPENAI_KEY\");\nif (key == null || key.isBlank()) {\n    throw new IllegalStateException(\"OPENAI_KEY env var is not set\");\n}\nnew StaticTokenProvider(key);","handlingStrategy":"validation","validationCode":"String key = System.getenv(\"OPENAI_API_KEY\");\nif (key == null || key.isBlank()) {\n    throw new IllegalStateException(\"OPENAI_API_KEY is not set; cannot build StaticTokenProvider\");\n}\nnew StaticTokenProvider(key);","typeGuard":null,"tryCatchPattern":"try {\n    return new StaticTokenProvider(key);\n} catch (IllegalArgumentException e) {\n    // fail fast at startup with a clear message rather than at first request\n    throw new IllegalStateException(\"Missing API key: \" + e.getMessage(), e);\n}","preventionTips":["Set required API-key env vars in every deployment profile and verify in a startup check.","Use Spring @Value with a clear error or a @ConfigurationProperties validator so a missing key fails the context refresh loudly.","Keep secret rotation tooling that never writes an empty value."],"tags":["auth","api-key","validation","config","startup"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}