<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Script Tool with Optional Input Parameters and Parameter Validation in Python Questions</title>
    <link>https://community.esri.com/t5/python-questions/script-tool-with-optional-input-parameters-and/m-p/1618719#M74288</link>
    <description>&lt;P&gt;The code looks fine at first glance.&amp;nbsp; I think the validation might be throwing things off and setting param 1 and 2 existence to True.&lt;BR /&gt;&lt;BR /&gt;If it were me - I'd just set all the params to optional and use the messaging function in the validation.&lt;BR /&gt;I'd also throw in some AddMessage() s to figure out what might be going on if still not working as expected.&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;class ToolValidator:
  # Class to add custom behavior and properties to the tool and tool parameters.

    def __init__(self):
        # Set self.params for use in other validation methods.
        self.params = arcpy.GetParameterInfo()

    def initializeParameters(self):
        # Customize parameter properties. This method gets called when the
        # tool is opened.
        return

    def updateParameters(self):
        # Modify the values and properties of parameters before internal
        # validation is performed.

    def updateMessages(self):
        # Modify the messages created by internal validation for each tool
        # parameter. This method is called after internal validation.
        return
        feature_set_input = self.params[0].value
        x_coord_input = self.params[1].value
        y_coord_input = self.params[2].value

        if not feature_set_input and (x_coord_input is not None or y_coord_input is not None) :
            self.params[0].setErrorMessage("Warning - enter interactive feature or X and Y, not both.  Interactive feature input will take precedence if both supplied")
            self.params[1].setErrorMessage("Warning - enter interactive feature or X and Y, not both.  Interactive feature input will take precedence if both supplied")
            self.params[2].setErrorMessage("Warning - enter interactive feature or X and Y, not both.  Interactive feature input will take precedence if both supplied")
            

    # def isLicensed(self):
    #     # Set whether the tool is licensed to execute.
    #     return True

    # def postExecute(self):
    #     # This method takes place after outputs are processed and
    #     # added to the display.
    #     return&lt;/LI-CODE&gt;&lt;P&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;</description>
    <pubDate>Tue, 27 May 2025 21:44:26 GMT</pubDate>
    <dc:creator>DavidPike</dc:creator>
    <dc:date>2025-05-27T21:44:26Z</dc:date>
    <item>
      <title>Script Tool with Optional Input Parameters and Parameter Validation</title>
      <link>https://community.esri.com/t5/python-questions/script-tool-with-optional-input-parameters-and/m-p/1618702#M74287</link>
      <description>&lt;P&gt;I'm trying to understand how to build a script tool that has multiple optional input parameters in conjunction with parameter validation.&amp;nbsp; Basically, I give the user two options to input a location that gets fed into a buffer tool. The first input option is to use an interactive map click using a feature set on the back end.&amp;nbsp; The second option is to allow the user to manually enter coordinates as the input location for the buffer tool.&amp;nbsp; When I set up parameter validation to disable the option not being used, the code behind still looks for the parameter/s even though the input has been disabled. I can't figure out how to get it to ignore the parameters that are not being entered by the disabled input options. Any advice would be much appreciated.&lt;/P&gt;&lt;P&gt;Here's the main script behind the tool:&lt;/P&gt;&lt;LI-CODE lang="python"&gt;import arcpy

arcpy.overwriteOutput = True
output_SR = arcpy.SpatialReference(4326)
output_gdb = "%scratchGDB%"

location_by_featureset = arcpy.GetParameter(0)

if location_by_featureset:
    Buffer = arcpy.analysis.MultipleRingBuffer(location_by_featureset, output_gdb+"\Output_Buffer", "20", "Miles")
else:
    Lat_Int = int(arcpy.GetParameterAsText(1))
    Long_Int = int(arcpy.GetParameterAsText(2))
    point_location = arcpy.management.CreateFeatureclass(output_gdb, "Point_Loc", "Point", "", "Enabled", "Enabled", output_SR)
    point_loc = arcpy.Point(Long_Int, Lat_Int)
    with arcpy.da.InsertCursor(point_location, ["SHAPE@XY"]) as cursor:
        cursor.insertRow([point_loc])
    del cursor

    Buffer = arcpy.analysis.MultipleRingBuffer(point_location, output_gdb+"\Output_Buffer", "20", "Miles")

arcpy.SetParameter(3, Buffer)

arcpy.AddMessage("Process Complete")&lt;/LI-CODE&gt;&lt;P&gt;Here's the parameter validation code:&lt;/P&gt;&lt;LI-CODE lang="python"&gt;class ToolValidator:
  # Class to add custom behavior and properties to the tool and tool parameters.

    def __init__(self):
        # Set self.params for use in other validation methods.
        self.params = arcpy.GetParameterInfo()

    def initializeParameters(self):
        # Customize parameter properties. This method gets called when the
        # tool is opened.
        return

    def updateParameters(self):
        # Modify the values and properties of parameters before internal
        # validation is performed.
        if self.params[0].altered:
            self.params[1].enabled = False
            self.params[2].enabled = False
        if self.params[1].altered:
            self.params[0].enabled = False
        return

    def updateMessages(self):
        # Modify the messages created by internal validation for each tool
        # parameter. This method is called after internal validation.
        return

    # def isLicensed(self):
    #     # Set whether the tool is licensed to execute.
    #     return True

    # def postExecute(self):
    #     # This method takes place after outputs are processed and
    #     # added to the display.
    #     return&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 27 May 2025 20:28:52 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/script-tool-with-optional-input-parameters-and/m-p/1618702#M74287</guid>
      <dc:creator>ewmahaffey</dc:creator>
      <dc:date>2025-05-27T20:28:52Z</dc:date>
    </item>
    <item>
      <title>Re: Script Tool with Optional Input Parameters and Parameter Validation</title>
      <link>https://community.esri.com/t5/python-questions/script-tool-with-optional-input-parameters-and/m-p/1618719#M74288</link>
      <description>&lt;P&gt;The code looks fine at first glance.&amp;nbsp; I think the validation might be throwing things off and setting param 1 and 2 existence to True.&lt;BR /&gt;&lt;BR /&gt;If it were me - I'd just set all the params to optional and use the messaging function in the validation.&lt;BR /&gt;I'd also throw in some AddMessage() s to figure out what might be going on if still not working as expected.&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;class ToolValidator:
  # Class to add custom behavior and properties to the tool and tool parameters.

    def __init__(self):
        # Set self.params for use in other validation methods.
        self.params = arcpy.GetParameterInfo()

    def initializeParameters(self):
        # Customize parameter properties. This method gets called when the
        # tool is opened.
        return

    def updateParameters(self):
        # Modify the values and properties of parameters before internal
        # validation is performed.

    def updateMessages(self):
        # Modify the messages created by internal validation for each tool
        # parameter. This method is called after internal validation.
        return
        feature_set_input = self.params[0].value
        x_coord_input = self.params[1].value
        y_coord_input = self.params[2].value

        if not feature_set_input and (x_coord_input is not None or y_coord_input is not None) :
            self.params[0].setErrorMessage("Warning - enter interactive feature or X and Y, not both.  Interactive feature input will take precedence if both supplied")
            self.params[1].setErrorMessage("Warning - enter interactive feature or X and Y, not both.  Interactive feature input will take precedence if both supplied")
            self.params[2].setErrorMessage("Warning - enter interactive feature or X and Y, not both.  Interactive feature input will take precedence if both supplied")
            

    # def isLicensed(self):
    #     # Set whether the tool is licensed to execute.
    #     return True

    # def postExecute(self):
    #     # This method takes place after outputs are processed and
    #     # added to the display.
    #     return&lt;/LI-CODE&gt;&lt;P&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;</description>
      <pubDate>Tue, 27 May 2025 21:44:26 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/script-tool-with-optional-input-parameters-and/m-p/1618719#M74288</guid>
      <dc:creator>DavidPike</dc:creator>
      <dc:date>2025-05-27T21:44:26Z</dc:date>
    </item>
    <item>
      <title>Re: Script Tool with Optional Input Parameters and Parameter Validation</title>
      <link>https://community.esri.com/t5/python-questions/script-tool-with-optional-input-parameters-and/m-p/1618869#M74290</link>
      <description>&lt;P&gt;Your code looks good; logic enables and disables correctly, but it doesn't re-enable parameters.&amp;nbsp;&lt;/P&gt;&lt;P&gt;Try this below code for validation&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="c"&gt;class ToolValidator:
  # Class to add custom behavior and properties to the tool and tool parameters.

    def __init__(self):
        # Set self.params for use in other validation methods.
        self.params = arcpy.GetParameterInfo()

    def initializeParameters(self):
        # Customize parameter properties. This method gets called when the
        # tool is opened.
        return

    def updateParameters(self):
        # If FeatureSet is altered, disable manual inputs
        if self.params[0].altered and self.params[0].value:
            self.params[1].enabled = False  # Latitude
            self.params[2].enabled = False  # Longitude
        # If Latitude or Longitude is altered, disable FeatureSet
        elif (self.params[1].altered and self.params[1].value) or (self.params[2].altered and self.params[2].value):
            self.params[0].enabled = False
        else:
            # Re-enable all if nothing is filled out
            self.params[0].enabled = True
            self.params[1].enabled = True
            self.params[2].enabled = True

    def updateMessages(self):
        return
            

    # def isLicensed(self):
    #     # Set whether the tool is licensed to execute.
    #     return True

    # def postExecute(self):
    #     # This method takes place after outputs are processed and
    #     # added to the display.
    #     return&lt;/LI-CODE&gt;</description>
      <pubDate>Wed, 28 May 2025 14:24:20 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/script-tool-with-optional-input-parameters-and/m-p/1618869#M74290</guid>
      <dc:creator>PandiyanKesavan</dc:creator>
      <dc:date>2025-05-28T14:24:20Z</dc:date>
    </item>
    <item>
      <title>Re: Script Tool with Optional Input Parameters and Parameter Validation</title>
      <link>https://community.esri.com/t5/python-questions/script-tool-with-optional-input-parameters-and/m-p/1618894#M74291</link>
      <description>&lt;P&gt;This is a bit of an over-answer, but have you considered using pyt/python toolboxes?&lt;/P&gt;&lt;LI-CODE lang="python"&gt;from pathlib import Path

from arcpy import (
    Parameter, 
    SpatialReference,
    Point,
    PointGeometry,
    AddMessage, 
    AddWarning, 
    AddError,
    EnvManager,
)

from arcpy.mp import ArcGISProject
from arcpy.da import SearchCursor, InsertCursor
from arcpy.management import CopyFeatures
from arcpy.analysis import Buffer

class Toolbox(object):
    def __init__(self):
        self.label = "Point Tools"
        self.alias = "PointTools"
        self.tools: list[type] = [BufferLoc]

class BufferLoc:
    
    def __init__(self) -&amp;gt; None:
        self.description = "Buffers a specified Location by the specified distance"
        self.label = "Buffer Loc"
        
        # Tool Constants
        self.reference = SpatialReference(4326)
        self.project = ArcGISProject('CURRENT')
        self.scratch = self.project.defaultGeodatabase 
        return

    def getParameterInfo(self):
        
        features = Parameter(
            name="features",
            displayName="Features",
            direction="Input",
            datatype="GPFeatureLayer",
            parameterType="Optional"
        )
        features.filter.list = ['Point']
        
        latitude = Parameter(
            name="latitude",
            displayName="Latitude",
            direction="Input",
            datatype="GPDouble",
            parameterType="Optional",
        )
        
        longitude = Parameter(
            name="longitude",
            displayName="Longitude",
            direction="Input",
            datatype="GPDouble",
            parameterType="Optional",
        )
        
        buffer_distance = Parameter(
            name="buffer_distance",
            displayName="Buffer Distance",
            direction="Input",
            datatype="GPLinearUnit",
            parameterType="Required",
        )
        buffer_distance.value = "20 Miles"
        
        method = Parameter(
            name="method",
            displayName="Method",
            direction="Input",
            datatype="GPString",
            parameterType="Required",
        )
        method.filter.list = ['GEODESIC', 'PLANAR']
        method.value = 'GEODESIC'
        
        output_database = Parameter(
            name="output_database",
            displayName="Output Database",
            direction="Input",
            datatype="DEWorkspace",
            parameterType="Required", 
        )
        output_database.value = self.scratch
        
        return [features, latitude, longitude, buffer_distance, method, output_database]

    def updateParameters(self, parameters: list[Parameter]) -&amp;gt; None:
        params = {p.name: p for p in parameters}
        
        # If features value is set, disable lat/lon
        params['latitude'].enabled = not params['features'].value
        params['longitude'].enabled = not params['features'].value
        
        # If lat or lon is set, disable features
        params['features'].enabled = not (params['latitude'].value or params['longitude'].value)
        
    def updateMessages(self, parameters: list[Parameter]): ...

    def isLicensed(self):
        return True

    def execute(self, parameters: list[Parameter], messages: list) -&amp;gt; None:
        params = {p.name: p for p in parameters}
        
        # Assign validated parameters
        features = params['features'].value
        latitude = params['latitude'].value
        longitude = params['longitude'].value
        output_database = Path(params['output_database'].valueAsText)
        buffer_distance = params['buffer_distance'].value
        method = params['method'].value
        
        # Do the Buffer
        AddMessage("Buffering Points...")
        try:
            if not features:
                features = CopyFeatures([PointGeometry(Point(longitude, latitude), self.reference)], "memory/temp_points")
            with EnvManager(overwriteOutput=True):
                res = Buffer(
                    in_features=features,
                    out_feature_class=str(output_database / "Output_Buffer"), 
                    buffer_distance_or_field=buffer_distance,
                    line_side='FULL',       # Create Parameter for this?     
                    line_end_type='ROUND',  # Create Parameter for this?
                    dissolve_option='NONE', # Create Parameter for this?
                    method=method
                )
        except Exception as e:
            AddError(f"Buffering Failed!:\n{e}")
            return
        AddMessage(f"Process Complete:\n\t{res.getMessages(0)}")
        if warn := res.getMessages(1):
            AddWarning('\t'+warn)
        if err := res.getMessages(2):
            AddError('\t'+err)
        
    def postExecute(self): ...&lt;/LI-CODE&gt;</description>
      <pubDate>Wed, 28 May 2025 15:08:28 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/script-tool-with-optional-input-parameters-and/m-p/1618894#M74291</guid>
      <dc:creator>HaydenWelch</dc:creator>
      <dc:date>2025-05-28T15:08:28Z</dc:date>
    </item>
    <item>
      <title>Re: Script Tool with Optional Input Parameters and Parameter Validation</title>
      <link>https://community.esri.com/t5/python-questions/script-tool-with-optional-input-parameters-and/m-p/1618904#M74292</link>
      <description>&lt;P&gt;Thanks&amp;nbsp;&lt;A href="https://community.esri.com/t5/user/viewprofilepage/user-id/584793" target="_self"&gt;&lt;SPAN class=""&gt;&lt;a href="https://community.esri.com/t5/user/viewprofilepage/user-id/584793"&gt;@PandiyanKesavan&lt;/a&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/A&gt;&lt;/P&gt;&lt;DIV class=""&gt;&lt;DIV class=""&gt;&lt;SPAN&gt;I swapped out my validation code with yours, and it seems like it's still expecting an input value for the FeatureSet when I try to manually enter the Lat/Longs. It worked fine when I selected the interactive click entry that produces the FeatureSet.&amp;nbsp; Here's the error:&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ewmahaffey_1-1748445632052.png" style="width: 400px;"&gt;&lt;img src="https://community.esri.com/t5/image/serverpage/image-id/133346i6E1AAAF5557D635B/image-size/medium?v=v2&amp;amp;px=400" role="button" title="ewmahaffey_1-1748445632052.png" alt="ewmahaffey_1-1748445632052.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 28 May 2025 16:27:10 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/script-tool-with-optional-input-parameters-and/m-p/1618904#M74292</guid>
      <dc:creator>ewmahaffey</dc:creator>
      <dc:date>2025-05-28T16:27:10Z</dc:date>
    </item>
    <item>
      <title>Re: Script Tool with Optional Input Parameters and Parameter Validation</title>
      <link>https://community.esri.com/t5/python-questions/script-tool-with-optional-input-parameters-and/m-p/1618942#M74293</link>
      <description>&lt;P&gt;Thanks David.&amp;nbsp; I have all of the input parameters set as optional, but for whatever reason the tool still expects the the FeatureSet input param (0) to be populated if I choose to manually enter the coordinates. I think I need to use some more conditional statements, but I haven't figured that out yet.&lt;/P&gt;</description>
      <pubDate>Wed, 28 May 2025 17:06:04 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/script-tool-with-optional-input-parameters-and/m-p/1618942#M74293</guid>
      <dc:creator>ewmahaffey</dc:creator>
      <dc:date>2025-05-28T17:06:04Z</dc:date>
    </item>
    <item>
      <title>Re: Script Tool with Optional Input Parameters and Parameter Validation</title>
      <link>https://community.esri.com/t5/python-questions/script-tool-with-optional-input-parameters-and/m-p/1619024#M74294</link>
      <description>&lt;P&gt;OK, I think I've something working that uses a little of what each of you had recommended. I ended having to use a Try/Except statement in the main script to allow the tool to get past some of the parameters.&amp;nbsp; I'm not sure if it's correct, but it works. I plan to add some defaults for layer symbology, etc.&amp;nbsp; Thanks all!&lt;/P&gt;&lt;P&gt;Main Script:&lt;/P&gt;&lt;LI-CODE lang="python"&gt;import arcpy

arcpy.overwriteOutput = True
output_SR = arcpy.SpatialReference(4326)
#output_gdb = "%scratchGDB%"
arcpy.env.workspace = r"C:\Workspace\SMADS\Tool_Migration\Tool_Migration\Default.gdb"
output_gdb = arcpy.env.workspace

try:
    location_by_featureset = arcpy.GetParameter(0)
    Buffer = arcpy.analysis.MultipleRingBuffer(location_by_featureset, output_gdb+"\Output_Buffer", "20", "Miles")
except:
    Lat_Int = int(arcpy.GetParameterAsText(1))
    Long_Int = int(arcpy.GetParameterAsText(2))
    point_location = arcpy.management.CreateFeatureclass(output_gdb, "Point_Loc", "Point", "", "Enabled", "Enabled", output_SR)
    point_loc = arcpy.Point(Long_Int, Lat_Int)
    with arcpy.da.InsertCursor(point_location, ["SHAPE@XY"]) as cursor:
        cursor.insertRow([point_loc])
    del cursor

    Buffer = arcpy.analysis.MultipleRingBuffer(point_location, output_gdb+"\Output_Buffer", "20", "Miles")
    arcpy.SetParameter(4, point_location)
    
arcpy.SetParameter(3, Buffer)

arcpy.AddMessage("Process Complete")&lt;/LI-CODE&gt;&lt;P&gt;Validation Script:&lt;/P&gt;&lt;LI-CODE lang="python"&gt;class ToolValidator:
  # Class to add custom behavior and properties to the tool and tool parameters.

    def __init__(self):
        # Set self.params for use in other validation methods.
        self.params = arcpy.GetParameterInfo()

    def initializeParameters(self):
        # Customize parameter properties. This method gets called when the
        # tool is opened.
        return

    def updateParameters(self):
        # Modify the values and properties of parameters before internal
        # validation is performed.
        
        # If FeatureSet is altered, disable manual inputs
        if self.params[0].altered and self.params[0].value:
            self.params[1].enabled = False  # Latitude
            self.params[2].enabled = False  # Longitude
        # If Latitude or Longitude is altered, disable FeatureSet
        elif (self.params[1].altered and self.params[1].value) or (self.params[2].altered and self.params[2].value):
            self.params[0].enabled = False
        else:
            # Re-enable all if nothing is filled out
            self.params[0].enabled = True
            self.params[1].enabled = True
            self.params[2].enabled = True
        return

    def updateMessages(self):
        # Modify the messages created by internal validation for each tool
        # parameter. This method is called after internal validation.

        return

    # def isLicensed(self):
    #     # Set whether the tool is licensed to execute.
    #     return True

    # def postExecute(self):
    #     # This method takes place after outputs are processed and
    #     # added to the display.
    #     return&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 28 May 2025 18:30:43 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/script-tool-with-optional-input-parameters-and/m-p/1619024#M74294</guid>
      <dc:creator>ewmahaffey</dc:creator>
      <dc:date>2025-05-28T18:30:43Z</dc:date>
    </item>
    <item>
      <title>Re: Script Tool with Optional Input Parameters and Parameter Validation</title>
      <link>https://community.esri.com/t5/python-questions/script-tool-with-optional-input-parameters-and/m-p/1619049#M74295</link>
      <description>&lt;P&gt;Try the below code, Hope this works for you&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="c"&gt;import arcpy

arcpy.overwriteOutput = True
output_SR = arcpy.SpatialReference(4326)
output_gdb = arcpy.env.scratchGDB

# Get parameters
input_featureset = arcpy.GetParameter(0)       # FeatureSet (optional)
lat_text = arcpy.GetParameterAsText(1)         # Latitude (optional)
lon_text = arcpy.GetParameterAsText(2)         # Longitude (optional)
output_buffer = arcpy.GetParameterAsText(3)    # Output feature class

geometry = None

# Option 1: Map click
if input_featureset:
    try:
        features = [row[0] for row in arcpy.da.SearchCursor(input_featureset, ["SHAPE@"])]
        if features:
            geometry = features[0]
            arcpy.AddMessage("Using location from map click.")
    except:
        pass

# Option 2: Manual coordinate input
if not geometry and lat_text and lon_text:
    try:
        lat = float(lat_text)
        lon = float(lon_text)
        geometry = arcpy.PointGeometry(arcpy.Point(lon, lat), output_SR)
        arcpy.AddMessage("Using manually entered coordinates.")
    except:
        arcpy.AddError("Invalid manual coordinates. Must be valid decimal numbers.")
        raise arcpy.ExecuteError

if not geometry:
    arcpy.AddError("No valid input location provided. Provide either a map click or coordinates.")
    raise arcpy.ExecuteError

# Create in-memory point feature class
point_fc = arcpy.management.CreateFeatureclass("in_memory", "point_temp", "POINT", spatial_reference=output_SR)
with arcpy.da.InsertCursor(point_fc, ["SHAPE@"]) as cursor:
    cursor.insertRow([geometry])

# Run Multiple Ring Buffer
arcpy.AddMessage("Running Multiple Ring Buffer...")
buffer_result = arcpy.analysis.MultipleRingBuffer(point_fc, output_buffer, ["20"], "Miles")

arcpy.AddMessage("Buffer complete. Output saved at: " + buffer_result.getOutput(0))
arcpy.SetParameter(3, buffer_result)&lt;/LI-CODE&gt;&lt;LI-CODE lang="c"&gt;class ToolValidator:
    def __init__(self):
        self.params = arcpy.GetParameterInfo()

    def updateParameters(self):
        # Get parameter values
        feature_set = self.params[0].value
        lat = self.params[1].value
        lon = self.params[2].value

        # If FeatureSet is used, disable lat/lon
        if feature_set:
            self.params[1].enabled = False
            self.params[2].enabled = False
        # If Lat or Lon is used, disable FeatureSet
        elif lat or lon:
            self.params[0].enabled = False
        else:
            # If nothing is entered, keep all enabled
            self.params[0].enabled = True
            self.params[1].enabled = True
            self.params[2].enabled = True

    def updateMessages(self):
        return&lt;/LI-CODE&gt;</description>
      <pubDate>Wed, 28 May 2025 19:30:46 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/script-tool-with-optional-input-parameters-and/m-p/1619049#M74295</guid>
      <dc:creator>PandiyanKesavan</dc:creator>
      <dc:date>2025-05-28T19:30:46Z</dc:date>
    </item>
    <item>
      <title>Re: Script Tool with Optional Input Parameters and Parameter Validation</title>
      <link>https://community.esri.com/t5/python-questions/script-tool-with-optional-input-parameters-and/m-p/1619058#M74297</link>
      <description>&lt;P&gt;I think what might actually be happening is that the if is always evaluating to True, probably because the feature set relies on a template/schema (I think).&lt;BR /&gt;&lt;BR /&gt;The Try Except you've got as a workaround isn't recommended and a bit hacky.&lt;BR /&gt;I'd do an AddMessage to see the value of your parameter(0) each time, and if it is always True, you could just switch the logic to evaluate against the Lat Long params instead.&lt;/P&gt;</description>
      <pubDate>Wed, 28 May 2025 19:40:58 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/script-tool-with-optional-input-parameters-and/m-p/1619058#M74297</guid>
      <dc:creator>DavidPike</dc:creator>
      <dc:date>2025-05-28T19:40:58Z</dc:date>
    </item>
    <item>
      <title>Re: Script Tool with Optional Input Parameters and Parameter Validation</title>
      <link>https://community.esri.com/t5/python-questions/script-tool-with-optional-input-parameters-and/m-p/1619274#M74298</link>
      <description>&lt;P&gt;I can't find the page that documents it, but you can make parameters conditionally required in updateMessages()&lt;/P&gt;&lt;LI-CODE lang="python"&gt;if (SOUR_TABL.value == "This is bad"): 
    INPUT_TBL.setIDMessage('ERROR', 735)&lt;/LI-CODE&gt;&lt;P&gt;Just make the parameter optional and then do this.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 29 May 2025 14:45:57 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/script-tool-with-optional-input-parameters-and/m-p/1619274#M74298</guid>
      <dc:creator>AlfredBaldenweck</dc:creator>
      <dc:date>2025-05-29T14:45:57Z</dc:date>
    </item>
    <item>
      <title>Re: Script Tool with Optional Input Parameters and Parameter Validation</title>
      <link>https://community.esri.com/t5/python-questions/script-tool-with-optional-input-parameters-and/m-p/1620204#M74313</link>
      <description>&lt;P&gt;Sorry for the delayed response.&amp;nbsp; I had to shift to another task for a couple of days. Anyhow, thanks! This code worked. I tweaked it just a bit so that the output buffer was set as a fixed f-class instead of a text input.&amp;nbsp; I also set the point f-class that's generated by the manual coordinate input to not be stored in memory.&amp;nbsp; This is just so that I can reference the point using either input method.&amp;nbsp; Thanks to everyone for helping be better understand how this all works.&amp;nbsp;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Here's the main script for the tool:&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;import arcpy

arcpy.overwriteOutput = True
output_SR = arcpy.SpatialReference(4326)
output_gdb = arcpy.env.scratchGDB

# Get parameters
input_featureset = arcpy.GetParameter(0)       # FeatureSet (optional)
lat_text = arcpy.GetParameterAsText(1)         # Latitude (optional)
lon_text = arcpy.GetParameterAsText(2)         # Longitude (optional)
#output_gdb = arcpy.GetParameterAsText(3)    # Output feature class

geometry = None

# Option 1: Map click
if input_featureset:
    try:
        features = [row[0] for row in arcpy.da.SearchCursor(input_featureset, ["SHAPE@"])]
        if features:
            geometry = features[0]
            arcpy.AddMessage("Using location from map click.")
    except:
        pass

# Option 2: Manual coordinate input
if not geometry and lat_text and lon_text:
    try:
        lat = float(lat_text)
        lon = float(lon_text)
        geometry = arcpy.PointGeometry(arcpy.Point(lon, lat), output_SR)
        arcpy.AddMessage("Using manually entered coordinates.")
    except:
        arcpy.AddError("Invalid manual coordinates. Must be valid decimal numbers.")
        raise arcpy.ExecuteError

if not geometry:
    arcpy.AddError("No valid input location provided. Provide either a map click or coordinates.")
    raise arcpy.ExecuteError

# Create in-memory point feature class
point_fc = arcpy.management.CreateFeatureclass(output_gdb, "point_temp", "POINT", spatial_reference=output_SR)
with arcpy.da.InsertCursor(point_fc, ["SHAPE@"]) as cursor:
    cursor.insertRow([geometry])
arcpy.SetParameter(4, point_fc)

# Run Multiple Ring Buffer
arcpy.AddMessage("Running Multiple Ring Buffer...")
buffer_result = arcpy.analysis.MultipleRingBuffer(point_fc, output_gdb+"\Output_Buffer", ["20"], "Miles")

arcpy.AddMessage("Buffer complete. Output saved at: " + buffer_result.getOutput(0))
arcpy.SetParameter(3, buffer_result)&lt;/LI-CODE&gt;&lt;P&gt;Here's the validation script&lt;/P&gt;&lt;LI-CODE lang="python"&gt;class ToolValidator:
    def __init__(self):
        self.params = arcpy.GetParameterInfo()

    def updateParameters(self):
        # Get parameter values
        feature_set = self.params[0].value
        lat = self.params[1].value
        lon = self.params[2].value

        # If FeatureSet is used, disable lat/lon
        if feature_set:
            self.params[1].enabled = False
            self.params[2].enabled = False
        # If Lat or Lon is used, disable FeatureSet
        elif lat or lon:
            self.params[0].enabled = False
        else:
            # If nothing is entered, keep all enabled
            self.params[0].enabled = True
            self.params[1].enabled = True
            self.params[2].enabled = True

    def updateMessages(self):
        return&lt;/LI-CODE&gt;</description>
      <pubDate>Mon, 02 Jun 2025 19:26:13 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/script-tool-with-optional-input-parameters-and/m-p/1620204#M74313</guid>
      <dc:creator>ewmahaffey</dc:creator>
      <dc:date>2025-06-02T19:26:13Z</dc:date>
    </item>
  </channel>
</rss>

