Custom node socket doesn't respect min_value or max_value

I have custom node tree with custom nodes/sockets. I’ve tried setting some sane defaults on my input sockets but Blender doesn’t seem to want to respect them. Example:

# In custom node class
def init(self, context):
    my_input ='MyCustomNodeSocket', "My Custom Socket")
    my_input.min_value = 0
    my_input.max_value = 1
    my_input.default_value = 0.5

When I change the value of the socket, it gladly moves above and below the parameters set above. default_value seems to work ok, though.

In a possibly similarly related issue, Blender doesn’t respect the “slider” parameter when I draw the property either.

# In MyCustomNodeSocket class
def draw_prop(self, context, layout, node, text):
        ''' This method can be overridden by subclasses as-needed '''
        layout.prop(self, "default_value", text=text, slider=True)

I expect to see the blue slider property like you see in other areas of the UI, but instead it’s just the regular float property with no blue slider. Am I missing something obvious here? There are no errors in the console to see either.

I don’t know much about nodes but you should take a look at the Blender 's template

I modified line 80 to add min and max, and line 107 to get a slider.

Here the modified template : 
import bpy
from bpy.types import NodeTree, Node, NodeSocket

# Implementation of custom nodes from Python

# Derived from the NodeTree base type, similar to Menu, Operator, Panel, etc.
class MyCustomTree(NodeTree):
    # Description string
    '''A custom node tree type that will show up in the editor type list'''
    # Optional identifier string. If not explicitly defined, the python class name is used.
    bl_idname = 'CustomTreeType'
    # Label for nice name display
    bl_label = "Custom Node Tree"
    # Icon identifier
    bl_icon = 'NODETREE'

# Custom socket type
class MyCustomSocket(NodeSocket):
    # Description string
    '''Custom node socket type'''
    # Optional identifier string. If not explicitly defined, the python class name is used.
    bl_idname = 'CustomSocketType'
    # Label for nice name display
    bl_label = "Custom Node Socket"

    # Enum items list
    my_items = (
        ('DOWN', "Down", "Where your feet are"),
        ('UP', "Up", "Where your head should be"),
        ('LEFT', "Left", "Not right"),
        ('RIGHT', "Right", "Not left"),

    my_enum_prop: bpy.props.EnumProperty(
        description="Just an example",

    # Optional function for drawing the socket input value
    def draw(self, context, layout, node, text):
        if self.is_output or self.is_linked:
            layout.prop(self, "my_enum_prop", text=text)

    # Socket color
    def draw_color(self, context, node):
        return (1.0, 0.4, 0.216, 0.5)

# Mix-in class for all custom nodes in this tree type.
# Defines a poll function to enable instantiation.
class MyCustomTreeNode:
    def poll(cls, ntree):
        return ntree.bl_idname == 'CustomTreeType'

# Derived from the Node base type.
class MyCustomNode(Node, MyCustomTreeNode):
    # === Basics ===
    # Description string
    '''A custom node'''
    # Optional identifier string. If not explicitly defined, the python class name is used.
    bl_idname = 'CustomNodeType'
    # Label for nice name display
    bl_label = "Custom Node"
    # Icon identifier
    bl_icon = 'SOUND'

    # === Custom Properties ===
    # These work just like custom properties in ID data blocks
    # Extensive information can be found under
    my_string_prop: bpy.props.StringProperty()
    my_float_prop: bpy.props.FloatProperty(default=3.1415926, min=0, max=10)

    # === Optional Functions ===
    # Initialization function, called when a new node is created.
    # This is the most common place to create the sockets for a node, as shown below.
    # NOTE: this is not the same as the standard __init__ function in Python, which is
    #       a purely internal Python method and unknown to the node system!
    def init(self, context):'CustomSocketType', "Hello")'NodeSocketFloat', "World")'NodeSocketVector', "!")'NodeSocketColor', "How")'NodeSocketColor', "are")'NodeSocketFloat', "you")

    # Copy function to initialize a copied node from an existing one.
    def copy(self, node):
        print("Copying from node ", node)

    # Free function to clean up on removal.
    def free(self):
        print("Removing node ", self, ", Goodbye!")

    # Additional buttons displayed on the node.
    def draw_buttons(self, context, layout):
        layout.label(text="Node settings")
        layout.prop(self, "my_float_prop", slider=True)

    # Detail buttons in the sidebar.
    # If this function is not defined, the draw_buttons function is used instead
    def draw_buttons_ext(self, context, layout):
        layout.prop(self, "my_float_prop")
        # my_string_prop button will only be visible in the sidebar
        layout.prop(self, "my_string_prop")

    # Optional: custom label
    # Explicit user label overrides this, but here we can define a label dynamically
    def draw_label(self):
        return "I am a custom node"

### Node Categories ###
# Node categories are a python system for automatically
# extending the Add menu, toolbar panels and search operator.
# For more examples see release/scripts/startup/

import nodeitems_utils
from nodeitems_utils import NodeCategory, NodeItem

# our own base class with an appropriate poll function,
# so the categories only show up in our own tree type

class MyNodeCategory(NodeCategory):
    def poll(cls, context):
        return context.space_data.tree_type == 'CustomTreeType'

# all categories in a list
node_categories = [
    # identifier, label, items list
    MyNodeCategory('SOMENODES', "Some Nodes", items=[
        # our basic node
    MyNodeCategory('OTHERNODES', "Other Nodes", items=[
        # the node item can have additional settings,
        # which are applied to new nodes
        # NB: settings values are stored as string expressions,
        # for this reason they should be converted to strings using repr()
        NodeItem("CustomNodeType", label="Node A", settings={
            "my_string_prop": repr("Lorem ipsum dolor sit amet"),
            "my_float_prop": repr(1.0),
        NodeItem("CustomNodeType", label="Node B", settings={
            "my_string_prop": repr("consectetur adipisicing elit"),
            "my_float_prop": repr(2.0),

classes = (

def register():
    from bpy.utils import register_class
    for cls in classes:

    nodeitems_utils.register_node_categories('CUSTOM_NODES', node_categories)

def unregister():

    from bpy.utils import unregister_class
    for cls in reversed(classes):

if __name__ == "__main__":

@Elreenys I tested it too, and I see that it’s working but the float value you edited is a FloatProperty, not a NodeSocket. It seems like when you try to apply the same logic to NodeSocket objects it falls apart. This is why I’m wondering if there’s something obvious I’m just missing here.

UPDATE: I fixed the slider issue - it turns out a socket subclass was overriding the draw method and not including the slider parameter. Still having trouble with mins and maxes though.