{"record":{"id":"a0bf2899a2da06c0","repo":"semaphoreui/semaphore","slug":"empty-token","errorCode":null,"errorMessage":"Empty token","messagePattern":"Empty token","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/cmd/runner_register.go","lineNumber":43,"sourceCode":"func init() {\n\trunnerRegisterCmd.PersistentFlags().BoolVar(&runnerRegisterArgs.stdinRegistrationToken, \"stdin-registration-token\", false, \"Read registration token from stdin\")\n\trunnerRegisterCmd.PersistentFlags().StringVar(&runnerRegisterArgs.name, \"name\", \"\", \"Runner name to register with\")\n\trunnerRegisterCmd.PersistentFlags().StringSliceVar(&runnerRegisterArgs.tags, \"tags\", nil, \"Runner tags (comma-separated or repeat the flag)\")\n\trunnerRegisterCmd.PersistentFlags().StringVar(&runnerRegisterArgs.webhook, \"webhook\", \"\", \"Runner webhook URL\")\n\trunnerRegisterCmd.PersistentFlags().StringVar(&runnerRegisterArgs.registrationTokenFilePath, \"registration-token-file\", \"\", \"Read registration token from a file\")\n\trunnerRegisterCmd.PersistentFlags().BoolVar(&runnerRegisterArgs.enabled, \"enabled\", true, \"Enable or disable the runner on the server\")\n\trunnerRegisterCmd.PersistentFlags().IntVar(&runnerRegisterArgs.projectID, \"project-id\", 0, \"Project ID for project-level runner (global runner if not provided)\")\n\trunnerCmd.AddCommand(runnerRegisterCmd)\n}\n\nfunc readRegistrationTokenFromFile(path string) {\n\ttokenBytes, err := os.ReadFile(path)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tif len(tokenBytes) == 0 {\n\t\tpanic(\"Empty token\")\n\t}\n\n\tutil.Config.Runner.RegistrationToken = strings.TrimSpace(string(tokenBytes))\n}\n\nfunc initRunnerRegistrationToken() {\n\tif runnerRegisterArgs.registrationTokenFilePath != \"\" {\n\t\treadRegistrationTokenFromFile(runnerRegisterArgs.registrationTokenFilePath)\n\t\treturn\n\t}\n\n\tif util.Config.Runner.RegistrationTokenFile != \"\" {\n\t\treadRegistrationTokenFromFile(util.Config.Runner.RegistrationTokenFile)\n\t\treturn\n\t}\n\n\tif !runnerRegisterArgs.stdinRegistrationToken {\n\t\treturn","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/semaphoreui/semaphore/blob/1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa/cli/cmd/runner_register.go#L25-L61","documentation":"readRegistrationTokenFromFile panics when the registration-token file it reads is empty (len(tokenBytes) == 0). The runner needs a non-empty registration token to register with the server, and an empty file provides nothing to authenticate with.","triggerScenarios":"Passing --registration-token-file (or config) pointing to a file that exists but has zero bytes — e.g. created by `touch` or truncated by a failed secret mount — triggering panic(\"Empty token\").","commonSituations":"Kubernetes secret mounts not yet populated; CI pipelines creating placeholder files; accidental truncation when editing the token file.","solutions":["Put the actual registration token into the file (no need for a trailing newline; it is trimmed)","Regenerate a registration token from the server if you don't have one, and save it to the file","Verify the file is non-empty before launch: `wc -c tokenfile`"],"exampleFix":"// before\n$ touch /etc/semaphore/registration.token\n// after\n$ echo \"$REGISTRATION_TOKEN\" > /etc/semaphore/registration.token","handlingStrategy":"validation","validationCode":"[ -s /etc/semaphore/registration.token ] || { echo \"registration token file is empty\"; exit 1; }\nsemaphore runner register --registration-token-file /etc/semaphore/registration.token","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use `[ -s file ]` to check non-empty token files before launch","Fail fast in CI when secret mounts produce empty files","Regenerate tokens if unsure rather than reusing placeholder files","Trim/validate token contents when writing the file"],"tags":["runner","registration-token","empty-file","cli"],"backgroundTag":"empty-required-field","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"}