Script not working after updating to the latest version of InDesign
About ten years ago, I wrote a script that basically relinks missing links to images whose names are a little different. The new name is found using regExes. A couple of days ago, my client wrote me that running the script causes InDesign memory usage to bloat and finally run out of system memory.
I made a few tests in different versions: 2024/5/6
In InDesign 2024 (version 19.5), it works without any problems: both on Mac and Windows.
- On my Mac (iMac, 3,3 GHz 6-Core Intel Core i5, 8 GB 2667 MHz DDR4), it took 3 minutes, 22 seconds to relink 254 links. 1,26 secs. per link.
- On my old Windows notebook (Intel Core i5-3230M CPU @2.60GHz, 8 GB RAM), it took about 22 minutes to relink 107 links. Approx. 9 secs. per link.
In InDesign 2025 (version 20.3.1) and 2026 (version 21.2) on my Mac, it gets stuck on the 27th link, and InDesign hangs, gobbling all the memory in the Activity Monitor, so the only option is to force quit it.
I tried:
- Reducing the undo steps via the doScript command
- Initiating garbage collection in the JavaScript engine: first for every 10-th and then for each link.
- I tried using the experimental reinitLink() command instead of relink()
BTW, I tested it in the non-persisting 'main' engine.
Unfortunately, it didn't help. The result is always the same:


I think this is a problem with the recent InDesign versions (2025 & 2026), not the script.
Any ideas?
Below is the script:
var scriptName = "Relink images",
doc,
arr = [],
app.doScript(PreCheck, ScriptLanguage.JAVASCRIPT, undefined, ((File.fs == "Macintosh") ? UndoModes.ENTIRE_SCRIPT : UndoModes.FAST_ENTIRE_SCRIPT), "\"" + scriptName + "\" Script");
//===================================== FUNCTIONS ======================================
function Main() {
var link,
links = doc.links.everyItem().getElements(),
linksLength = links.length;
var progressWin, progressBar, progressTxt, countProgressBar;
progressWin = new Window("window", scriptName);
progressBar = progressWin.add("progressbar" , undefined, 0, linksLength);
progressBar.preferredSize.width = 800;
progressTxt = progressWin.add("statictext", undefined, "");
progressTxt.alignment = "fill";
progressWin.show();
var startTime = new Date();
arr.push(GetDate());
arr.push("\r\r------------------------------------------\rDocument name: " + doc.name + "\rDocument path: " + File(doc.filePath).fsName + "\r------------------------------------------");
for (var i = 0; i < links.length; i++) {
link = links[i];
countProgressBar = i + 1;
progressBar.value = countProgressBar;
progressTxt.text = "Relinking images: " + link.name + " (" + countProgressBar + " out of " + linksLength + ")";
$.writeln("# " + countProgressBar);
if (link.status == LinkStatus.LINK_MISSING) {
ProcessLink(link);
}
}
progressWin.close();
var endTime = new Date();
var duration = GetDuration(startTime, endTime);
var report = count + ((count == 1) ? " link was" : " links were") + " relinked.\n(time elapsed: " + duration + ")";
arr.push("\r=========================================================\r" + report + "\r=========================================================\r\r\r");
var text = arr.join("\r");
WriteToFile(text);
}
function ProcessLink(oldLink) {
var newFile = GetApproxNameFile(oldLink);
if (newFile != null) {
Relink(oldLink, newFile);
}
else {
arr.push("\rCan't get an image with approximate name for '" + oldLink.name + "'");
$.writeln("Can't get an image with approximate name for '" + oldLink.name + "'");
}
}
function GetApproxNameFile(oldLink) {
var jpegFile, newName, patt1, patt2, patt3, res1, res2, res3, str,
foundFile = null,
file = new File(oldLink.filePath),
folder = file.parent,
folderPath = folder.absoluteURI + "/",
oldName = decodeURI(oldLink.name);
if (folder.exists) {
var jpegFiles = folder.getFiles("*.jpg");
for (var i = 0; i < jpegFiles.length; i++) {
jpegFile = jpegFiles[i];
newName = decodeURI(jpegFile.name);
patt1 = /(.+?)([A-Z]{2,4})(.+?)(_(\d|X)(\d|X)(\d|X)(\d|X)\.(\d|X)(\d|X)\.(\d|X)(\d|X)_)(B[A-Z]{0,2}\d{1,4}.+?_)*(.+)/;
res1 = oldName.match(patt1);
if (res1 == null) {
continue;
}
str = decodeURI(res1[1] + "[A-Z]{2,4}" + res1[3] + res1[4] + "B[A-Z]{0,2}\\d{1,4}.+?_" + res1[14].replace(/^B[A-Z]{0,2}\d{1,4}.+?_/, ""));
patt2 = eval("/" + str + "/");
res2 = newName.match(patt2);
if (res2 != null) {
foundFile = jpegFile;
break;
}
else {
str = decodeURI(res1[1] + "[A-Z]{2,4}" + res1[3] + res1[4] + res1[14]);
patt3 = eval("/" + str + "/");
res3 = newName.match(patt3);
if (res3 != null) {
foundFile = jpegFile;
break;
}
}
} // end for
}
else {
arr.push("\rERROR: The folder where the link '" + oldName + "' originally was doesn't exist any more: '" + folderPath + "'");
$.writeln("Folder doesn't exist.");
}
return foundFile;
}
function Relink(oldLink, newFile) {
$.writeln("Relinking " + oldLink.name + ">" + newFile.name);
var oldPath = new File(oldLink.filePath).fullName;
oldLink.relink(newFile);
// oldLink.reinitLink("file:/" + newFile.fsName);
count++;
arr.push("\r" + oldLink.name + "\r" + "\tOld path: " + oldPath);
arr.push("\tNew path: " + newFile.fullName);
}
function PreCheck() {
if (app.documents.length == 0) ErrorExit("Please open a document and try again.", true);
doc = app.activeDocument;
if (doc.converted) ErrorExit("The current document has been modified by being converted from older version of InDesign. Please save the document and try again.", true);
if (!doc.saved) ErrorExit("The current document has not been saved since it was created. Please save the document and try again.", true);
Main();
}
function ErrorExit(error, icon) {
alert(error, scriptName, icon);
exit();
}
function GetDuration(startTime, endTime) {
var str;
var duration = (endTime - startTime)/1000;
duration = Math.round(duration);
if (duration >= 60) {
var minutes = Math.floor(duration/60);
var seconds = duration - (minutes * 60);
str = minutes + ((minutes != 1) ? " minutes, " : " minute, ") + seconds + ((seconds != 1) ? " seconds" : " second");
if (minutes >= 60) {
var hours = Math.floor(minutes/60);
minutes = minutes - (hours * 60);
str = hours + ((hours != 1) ? " hours, " : " hour, ") + minutes + ((minutes != 1) ? " minutes, " : " minute, ") + seconds + ((seconds != 1) ? " seconds" : " second");
}
}
else {
str = duration + ((duration != 1) ? " seconds" : " second");
}
return str;
}
function GetDate() {
var date = new Date();
if ((date.getYear() - 100) < 10) {
var year = "0" + new String((date.getYear() - 100));
}
else {
var year = new String((date.getYear() - 100));
}
var dateString = (date.getMonth() + 1) + "/" + date.getDate() + "/" + year + " " + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds();
return dateString;
}
function WriteToFile(text) {
var file = new File("~/Desktop/" + scriptName + ".txt");
file.encoding = "UTF-8";
if (file.exists) {
file.open("e");
file.seek(0, 2);
}
else {
file.open("w");
}
file.write(text);
file.close();
}

