{"record":{"id":"c5bd731e8dfe3c36","repo":"HKUDS/Vibe-Trading","slug":"token-issue-path-must-start-with","errorCode":null,"errorMessage":"token_issue_path must start with \"/\"","messagePattern":"token_issue_path must start with \"/\"","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/channels/websocket.py","lineNumber":122,"sourceCode":"        if not path.is_absolute():\n            raise ValueError(\"unix_socket_path must be an absolute path\")\n        return str(path)\n\n    @field_validator(\"path\")\n    @classmethod\n    def path_must_start_with_slash(cls, value: str) -> str:\n        if not value.startswith(\"/\"):\n            raise ValueError('path must start with \"/\"')\n        return _normalize_config_path(value)\n\n    @field_validator(\"token_issue_path\")\n    @classmethod\n    def token_issue_path_format(cls, value: str) -> str:\n        value = value.strip()\n        if not value:\n            return \"\"\n        if not value.startswith(\"/\"):\n            raise ValueError('token_issue_path must start with \"/\"')\n        return _normalize_config_path(value)\n\n    @model_validator(mode=\"after\")\n    def token_issue_path_differs_from_ws_path(self) -> Self:\n        if not self.token_issue_path:\n            return self\n        if _normalize_config_path(self.token_issue_path) == _normalize_config_path(self.path):\n            raise ValueError(\"token_issue_path must differ from path (the WebSocket upgrade path)\")\n        return self\n\n    @model_validator(mode=\"after\")\n    def wildcard_host_requires_auth(self) -> Self:\n        if self.host not in (\"0.0.0.0\", \"::\"):\n            return self\n        if self.token.strip() or self.token_issue_secret.strip():\n            return self\n        raise ValueError(\n            \"host is 0.0.0.0 (all interfaces) but neither token nor \"","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/channels/websocket.py#L104-L140","documentation":"Raised when token_issue_path is non-empty but does not start with '/'. token_issue_path defines the HTTP endpoint that issues auth tokens for the WebSocket channel; like the main path, it must be a root-relative URL path, which the validator enforces before normalizing it.","triggerScenarios":"Setting token_issue_path=\"issue\" or \"auth/token\" in config (empty string is allowed and skips validation). Any non-empty value not beginning with '/' raises.","commonSituations":"Configuring token issuance for the first time and reusing a route name without the slash; env var token_issue_path=token missing '/'; copying the value from documentation that showed it without a leading slash.","solutions":["Set token_issue_path: /token (leading slash required)","Leave it empty/omit it if you don't need token issuance over HTTP","Cross-check the related path field uses the same leading-slash convention"],"exampleFix":"# before\ntoken_issue_path = \"issue-token\"\n# after\ntoken_issue_path = \"/issue-token\"","handlingStrategy":"validation","validationCode":"if token_issue_path:\n    token_issue_path = \"/\" + token_issue_path.lstrip(\"/\")\n# empty string is fine (issuance disabled)","typeGuard":"def is_valid_issue_path(p: str) -> bool:\n    return p == \"\" or p.startswith(\"/\")","tryCatchPattern":null,"preventionTips":["Apply the same leading-slash normalization to every route field","Omit token_issue_path entirely if not using HTTP token issuance"],"tags":["websocket","token","path-validation","config-validation"],"backgroundTag":"config-validation-failed","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}