Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

illustrator crashes when running a script to loop through paths

Explorer ,
Nov 06, 2025 Nov 06, 2025

Hello,

Does anyone know why my illustrator is crashing when I run this script?  When I take out the loop for the pathItems, it does what I want.  It selects the group named "5".  Now I need to select all the paths with a specfic name like "50", but illustrator keep crashing.

 

var doc = app.activeDocument;


var activeLayer = doc.activeLayer;

var getLayer = doc.layers.getByName("clouds");


for (var i = 0; i < doc.layers.length; i++) {
layer = doc.layers[i];

if (layer.name === "clouds") {
//doc.activeLayer = doc.layers.getByName("clouds");

for (var ii = 0; ii < doc.groupItems.length; ii++) {
group = doc.groupItems[ii];

if (group.name === "5") {
//group.selected = true;

for (var p = 0; p< doc.pathItems.length; p++) {
path = doc.pathItems[p];

if (path.name === "50") {
path.selected = true;
alert("path loop success");

} // end path if statement
} // end path loop
} // end group if statement
} // end group loop
} // end layer if statement
} // end layer loop

TOPICS
How-to , Performance , Scripting
101
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe
Contributor ,
Nov 06, 2025 Nov 06, 2025

you are looping over yourself with the for loops. your layer loop has you looping through each item in that layer for every layer so you are revisiting the same items. without seeing the specific file, I'd expect this is why its "crashing" as its processing a lot.
If you're looking for just paths with a specific name you can remove all of the loops except the path items loop and then have the if path name == statement. 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 06, 2025 Nov 06, 2025

I'm not sure what you're trying to do but the way the script is layed out it seems you want to find a path named "50" that is inside a group named "5" that is inside a layer named "clouds"

 

if that's the case, then there's no need to query all groups and paths in other layers

 

if that's not your goal, then you need to elaborate and share more details

 

check if this edited script works

var doc = app.activeDocument;


var activeLayer = doc.activeLayer;

//var getLayer = doc.layers.getByName("clouds");


for (var i = 0; i < doc.layers.length; i++) {
    layer = doc.layers[i];

    if (layer.name === "clouds") {
        //doc.activeLayer = doc.layers.getByName("clouds");

        for (var ii = 0; ii < layer.groupItems.length; ii++) {  // ****edited
            group = layer.groupItems[ii];   // ****edited

            if (group.name === "5") {
                //group.selected = true;

                for (var p = 0; p < group.pathItems.length; p++) {  // ****edited
                    path = group.pathItems[p];  // ****edited

                    if (path.name === "50") {
                        path.selected = true;
                        alert("path loop success");

                    } // end path if statement
                } // end path loop
            } // end group if statement
        } // end group loop
    
    } // end layer if statement
} // end layer loop

 

 

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 08, 2025 Nov 08, 2025

Hi @amberw42080715 some things are faster and slower via the scripting API. One operation that is incredibly slow is setting a page item as "selected". The fastest way for multiple items is to set the selection to an array of page items—in one operation—as I show in the script below..

 

Also traversing a complex document looking through item names can be inefficient without some care. I have spent a lot of time crafting the `getItems` function (over several years!) and now I can pretty much throw anything at it and it can deliver the goods.

 

My example script doesn't check for GroupItem names, but if you read the getItems documentation you will see that it can handle it too, or you can add a predicate into the `selectByName` function to check the item's parent. Or you can do two calls to `getItems`, one for a group named X and another searching inside that group (pass it the parameter {from: myGroup}. Let me know if you'd like guidance on this.

- Mark

 

/**
 * @file Select Paths By Name.js
 *
 * Example using `getItems` function to select items by name.
 *
 * There are two main efficiencies:
 *   1. The `getItems` function collects items in a careful way
 *      rarely getting caught up in memory issues.
 *   2. The selection is made in one operation.
 *
 * @author m1b
 * @version 2025-11-09
 * @discussion https://community.adobe.com/t5/illustrator-discussions/illustrator-crashes-when-running-a-script-to-loop-through-paths/m-p/15580281
 */
(function () {

    if (0 === app.documents.length)
        return alert('Please open a document and try again.');

    var doc = app.activeDocument;

    var matchMe = prompt('Enter name to search for:', 'Untitled');

    if (!matchMe)
        return;

    /** Returns true when the item name matches the target. */
    function selectByName(item) {
        return item.name && item.name === matchMe;
    }

    var itemsToSelect = getItems({ from: doc, filter: selectByName })

    // select the items
    doc.selection = itemsToSelect;

})();

/** ------------------------------------------------------------------- *
 *  GET ITEMS                                                           *
 * -------------------------------------------------------------------- *
 * @author m1b                                                          *
 * @version 2024-03-01                                                  *
 * -------------------------------------------------------------------- *
 * Collects page items from a `from` source, eg. a Document, Layer,     *
 * GroupItem, or Array. Will look inside group items up to `maxDepth`.  *
 * Search can be filtered using `filter` function. Note that the        *
 * filter function is evaluated last in the filtering process.          *
 * -------------------------------------------------------------------- *
 * Example 1. Get all items in document:                                *
 *                                                                      *
 *    var myItems = getItems({ from: app.activeDocument });             *
 *                                                                      *
 * -------------------------------------------------------------------- *
 * Example 2. Get all selected items except groups:                     *
 *                                                                      *
 *    var myItems = getItems({                                          *
 *      from: app.activeDocument.selection,                             *
 *      getGroupItems: false,                                           *
 *    });                                                               *
 *                                                                      *
 * -------------------------------------------------------------------- *
 * Example 3. Using `filter` function to choose item type:              *
 *                                                                      *
 *    var myItems = getItems({                                          *
 *      from: app.activeDocument,                                       *
 *      filter: function (item) {                                       *
 *        return (                                                      *
 *          'PathItem' === item.typename                                *
 *          || 'CompoundPathItem' === item.typename                     *
 *        );                                                            *
 *      }                                                               *
 *    });                                                               *
 *                                                                      *
 * -------------------------------------------------------------------- *
 * Example 4. Using `filter` function:                                  *
 *                                                                      *
 *    var myItems = getItems({                                          *
 *      from: app.activeDocument,                                       *
 *      filter: onlyPngLinks                                            *
 *    });                                                               *
 *                                                                      *
 *    function onlyPngLinks(item, depth) {                              *
 *       return (                                                       *
 *           'PlacedItem' === item.typename                             *
 *           && '.png' === item.file.name.slice(-4).toLowerCase()       *
 *       );                                                             *
 *    };                                                                *
 *                                                                      *
 * -------------------------------------------------------------------- *
 * Example 4. Using the `filter` function for custom collecting:        *
 *                                                                      *
 * This example bypasses the normal returned array and instead          *
 * captures items in an "external" array `itemsByDepth`.                *
 *                                                                      *
 *    var itemsByDepth = [];                                            *
 *                                                                      *
 *    function getItemsByDepth(item, depth) {                           *
 *      if (undefined == itemsByDepth[depth])                           *
 *        itemsByDepth[depth] = [];                                     *
 *      itemsByDepth[depth].push(item);                                 *
 *    };                                                                *
 *                                                                      *
 *    getItems({                                                        *
 *      from: app.activeDocument,                                       *
 *      filter: getItemsByDepth                                         *
 *    });                                                               *
 *                                                                      *
 * -------------------------------------------------------------------- *
 * @param {Object} options - parameters
 * @param {PageItem|Array<PageItem>|Document|Layer} options.from - the thing(s) to look in, eg. a selection.
 * @param {Function} [options.filter] - function that, given a found item, must return true (default: no filtering).
 * @param {Boolean} [options.getPageItems] - whether to include page items in returned items (default: true).
 * @param {Boolean} [options.getGroupItems] - whether to include GroupItems in returned items (default: true).
 * @param {Boolean} [options.getLayers] - whether to include Layers in returned items (default: false).
 * @param {Boolean} [options.getHiddenItems] - whether to include hidden items in returned items (default: true).
 * @param {Boolean} [options.getLockedItems] - whether to include locked items in returned items (default: true).
 * @param {Boolean} [options.getGuideItems] - whether to include guide items in returned items (default: false).
 * @param {Number} [options.maxDepth] - deepest folder level (recursion depth limit) (default: 99).
 * @param {Boolean} [options.returnFirstMatch] - whether to return only the first found item (default: false).
 * @param {Number} [depth] - the current depth (private).
 * @returns {Array|PageItem} - all the found items in a flat array, or the first found item if `returnFirstMatch`.
 */
function getItems(options, depth) {

    // defaults
    options = options || {};

    var found = [],
        depth = depth || 0,
        items = options.from;

    if (!options.initialized)
        // once-off initialization
        if (!initialize())
            return [];

    itemsLoop:
    for (var i = 0, item, len = items.length; i < len; i++) {

        item = items[i];

        if (
            false === excludeFilter(item)
            && true === includeFilter(item)
        ) {
            // item found!
            found.push(item);

            if (options.returnFirstMatch)
                break itemsLoop;
        }

        if (
            'GroupItem' !== item.constructor.name
            && 'Layer' !== item.typename
        )
            // only items with children from here
            continue itemsLoop;

        if (
            excludeHidden(item)
            || excludeLocked(item)
        )
            // don't look into excluded containers
            continue itemsLoop;

        if (depth >= options.maxDepth)
            // don't go deeper
            continue itemsLoop;

        // set up for the next depth
        options.from = item.pageItems;

        // look inside
        found = found.concat(getItems(options, depth + 1));

    }

    // this level done
    if (true == options.returnFirstMatch)
        return found[0];
    else
        return found;

    /**
     * Returns true when the item should be not be found.
     * @param {PageItem|Layer} item
     * @returns {Boolean}
     */
    function excludeFilter(item) {

        return (

            isAlreadyFound(item)

            // is hidden
            || excludeHidden(item)

            // is locked
            || excludeLocked(item)

            // is guide
            || (
                false === options.getGuideItems
                && true === item.guides
            )

            // is layer
            || (
                false === options.getLayers
                && 'Layer' === item.typename
            )

            // is group item
            || (
                false === options.getGroupItems
                && 'GroupItem' === item.typename
            )

            // is page item
            || (
                false === options.getPageItems
                && 'GroupItem' !== item.typename
                && undefined != item.uuid
            )

        );

    };

    /**
     * Returns true when the item should be included.
     * @param {PageItem|Layer} item
     * @returns {Boolean}
     */
    function includeFilter(item) {

        return (
            undefined == options.filter
            || options.filter(item, depth)
        );

    };

    /**
     * Returns true when the item should
     * be excluded because it is hidden.
     * @param {PageItem|Layer} item
     * @returns {Boolean}
     */
    function excludeHidden(item) {

        return (
            false === options.getHiddenItems
            && (
                true === item.hidden
                || false === item.visible
            )
        );

    };

    /**
     * Returns true when the item should
     * be excluded because it is locked.
     * @param {PageItem|Layer} item
     * @returns {Boolean}
     */
    function excludeLocked(item) {

        return (
            false === options.getLockedItems
            && true === item.locked
        );

    };

    /**
     * Returns true if item was already
     * found, and marks item as found,
     * to avoid finding same item twice.
     * @param {PageItem|Layer} item
     * @returns {Boolean}
     */
    function isAlreadyFound(item) {

        var uuid = item.hasOwnProperty('uuid')
            ? item.uuid
            : item.typename + item.zOrderPosition,

            isFound = !!options.isFound[uuid];

        options.isFound[uuid] = true;

        return isFound;

    }

    /**
     * Returns the initialised `options` object.
     * @returns {Object}
     */
    function initialize() {

        // make a new object, so we don't pollute the original
        options = {
            initialized: true,
            depth: 0,
            isFound: {},
            filter: options.filter,
            getPageItems: false !== options.getPageItems,
            getGroupItems: false !== options.getGroupItems,
            getLayers: true === options.getLayers,
            getHiddenItems: false !== options.getHiddenItems,
            getLockedItems: false !== options.getLockedItems,
            getGuideItems: true === options.getGuideItems,
            maxDepth: options.maxDepth,
            returnFirstMatch: options.returnFirstMatch,
        };

        if (
            undefined == options.maxDepth
            || !options.maxDepth instanceof Number
        )
            options.maxDepth = 99;

        // items is a single layer
        if ('Layer' === items.typename)
            items = [items];

        // items is a document
        else if ('Document' === items.constructor.name) {

            var layers = items.layers;
            items = [];

            for (var i = 0; i < layers.length; i++)
                items.push(layers[i]);

        }

        else if ('Array' !== items.constructor.name)
            items = [items];

        return items.length > 0;

    };

};

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 09, 2025 Nov 09, 2025
LATEST

I should have made it clear that @CarlosCanto's excellent approach is the most efficient way if you know the structure of your document.

- Mark

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines