{"record":{"id":"b6d34b794819c032","repo":"grpc/grpc-go","slug":"tokenfilepath-cannot-be-empty","errorCode":null,"errorMessage":"tokenFilePath cannot be empty","messagePattern":"tokenFilePath cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"credentials/jwt/token_file_call_creds.go","lineNumber":57,"sourceCode":"type jwtTokenFileCallCreds struct {\n\tfileReader      *jwtFileReader\n\tbackoffStrategy backoff.Strategy\n\n\t// cached data protected by mu\n\tmu               sync.Mutex\n\tcachedAuthHeader string    // \"Bearer \" + token\n\tcachedExpiry     time.Time // Slightly less than actual expiration time\n\tcachedError      error     // Error from last failed attempt\n\tretryAttempt     int       // Current retry attempt number\n\tnextRetryTime    time.Time // When next retry is allowed\n\tpendingRefresh   bool      // Whether a refresh is currently in progress\n}\n\n// NewTokenFileCallCredentials creates PerRPCCredentials that reads JWT tokens\n// from the specified file path.\nfunc NewTokenFileCallCredentials(tokenFilePath string) (credentials.PerRPCCredentials, error) {\n\tif tokenFilePath == \"\" {\n\t\treturn nil, fmt.Errorf(\"tokenFilePath cannot be empty\")\n\t}\n\n\tcreds := &jwtTokenFileCallCreds{\n\t\tfileReader:      &jwtFileReader{tokenFilePath: tokenFilePath},\n\t\tbackoffStrategy: backoff.DefaultExponential,\n\t}\n\n\treturn creds, nil\n}\n\n// GetRequestMetadata gets the current request metadata, refreshing tokens if\n// required. This implementation follows the PerRPCCredentials interface.  The\n// tokens will get automatically refreshed if they are about to expire or if\n// they haven't been loaded successfully yet.\n// If it's not possible to extract a token from the file, UNAVAILABLE is\n// returned.\n// If the token is extracted but invalid, then UNAUTHENTICATED is returned.\n// If errors are encoutered, a backoff is applied before retrying.","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/credentials/jwt/token_file_call_creds.go#L39-L75","documentation":"Returned by NewTokenFileCallCredentials when tokenFilePath is the empty string. This is a pure programming error: the constructor refuses to create a credential that could never read a token. No I/O is attempted.","triggerScenarios":"Passing an unset struct field, empty env var, or zero-value string to NewTokenFileCallCredentials; a config load that silently defaulted the path to \"\".","commonSituations":"Missing TOKEN_FILE env var in the deployment; config YAML field misnamed so it deserializes to empty; refactoring that dropped the path argument.","solutions":["Pass a non-empty absolute path to NewTokenFileCallCredentials.","Validate the configured path at startup and fail fast with a clear message if empty.","Set the missing environment variable (e.g. TOKEN_FILE) in the container/pod spec."],"exampleFix":"// before\ncreds, err := jwt.NewTokenFileCallCredentials(os.Getenv(\"TOKEN_FILE\"))\n// after\npath := os.Getenv(\"TOKEN_FILE\")\nif path == \"\" {\n    log.Fatal(\"TOKEN_FILE env var is required\")\n}\ncreds, err := jwt.NewTokenFileCallCredentials(path)","handlingStrategy":"validation","validationCode":"if tokenFilePath == \"\" {\n    log.Fatal(\"tokenFilePath is required\")\n}\ncreds, err := jwt.NewTokenFileCallCredentials(tokenFilePath)","typeGuard":"func nonEmptyPath(p string) bool { return strings.TrimSpace(p) != \"\" }","tryCatchPattern":null,"preventionTips":["Validate the configured path at startup and fail fast.","Treat an empty TOKEN_FILE env var as a hard configuration error.","Centralize config loading so a missing field cannot silently become \"\"."],"tags":["grpc","jwt","validation","configuration"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}