{"record":{"id":"7fb19dcdc145569c","repo":"semaphoreui/semaphore","slug":"semaphore-runner-token-and-semaphore-runner-token","errorCode":null,"errorMessage":"SEMAPHORE_RUNNER_TOKEN and SEMAPHORE_RUNNER_TOKEN_FILE are mutually exclusive","messagePattern":"SEMAPHORE_RUNNER_TOKEN and SEMAPHORE_RUNNER_TOKEN_FILE are mutually exclusive","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/config.go","lineNumber":940,"sourceCode":"\n\tCookie = securecookie.New(hash, encryption)\n\n\tif Config.WebHost != \"\" {\n\t\tvar err error\n\t\tWebHostURL, err = url.Parse(Config.WebHost)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\tif len(WebHostURL.String()) == 0 {\n\t\t\tWebHostURL = nil\n\t\t}\n\t} else {\n\t\tWebHostURL = nil\n\t}\n\n\tif Config.Runner.Token != \"\" && Config.Runner.TokenFile != \"\" {\n\t\tpanic(\"SEMAPHORE_RUNNER_TOKEN and SEMAPHORE_RUNNER_TOKEN_FILE are mutually exclusive\")\n\t}\n\n\tif Config.Runner.TokenFile != \"\" {\n\t\trunnerTokenBytes, err := os.ReadFile(Config.Runner.TokenFile)\n\t\tif err == nil {\n\t\t\tConfig.Runner.Token = strings.TrimSpace(string(runnerTokenBytes))\n\t\t}\n\t}\n\n\tif Config.Subscription.KeyFile != \"\" {\n\t\tsubscriptionKeyBytes, err := os.ReadFile(Config.Subscription.KeyFile)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\tConfig.Subscription.Key = strings.TrimSpace(string(subscriptionKeyBytes))\n\t}\n","sourceCodeStart":922,"sourceCodeEnd":958,"githubUrl":"https://github.com/semaphoreui/semaphore/blob/1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa/util/config.go#L922-L958","documentation":"Panics from ConfigInit in util/config.go when both the runner token (SEMAPHORE_RUNNER_TOKEN) and the runner token file (SEMAPHORE_RUNNER_TOKEN_FILE) are set at the same time. It is a startup validation guard: the two are alternative ways to supply the same secret, and allowing both would make it ambiguous which token is authoritative, so the process refuses to start until exactly one is configured.","triggerScenarios":"Thrown at util/config.go:940 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Keep only one of the two settings: remove SEMAPHORE_RUNNER_TOKEN or unset runner_token_file / SEMAPHORE_RUNNER_TOKEN_FILE","If you intended to switch from an inline token to a file, clear the old token value before setting the token file path","Audit deployment manifests and .env files for both variables being injected simultaneously"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa","analyzedAt":"2026-09-07T11:00:33.293Z","contentChangedAt":"2026-09-07T11:00:33.293Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}