What causes the error "Can't execute code from a freed script"

I thought I'd found the solution a while ago (see my blog):

If you ever get the JavaScript (or should that be JScript) error "Can't execute code from a freed script" - try moving any meta tags in the head so that they're before your script tags.

...but based on one of the most recent blog comments, the fix I suggested may not work for everyone. I thought this would be a good one to open up to the StackOverflow community....

What causes the error "Can't execute code from a freed script" and what are the solutions/workarounds?


You get this error when you call a function that was created in a window or frame that no longer exists.

If you don't know in advance if the window still exists, you can do a try/catch to detect it:

try
{
  f();
}
catch(e)
{
  if (e.number == -2146823277)
    // f is no longer available
    ...
}

The error is caused when the 'parent' window of script is disposed (ie: closed) but a reference to the script which is still held (such as in another window) is invoked. Even though the 'object' is still alive, the context in which it wants to execute is not.

It's somewhat dirty, but it works for my Windows Sidebar Gadget:

Here is the general idea: The 'main' window sets up a function which will eval'uate some code, yup, it's that ugly. Then a 'child' can call this "builder function" (which is /bound to the scope of the main window/) and get back a function which is also bound to the 'main' window. An obvious disadvantage is, of course, that the function being 'rebound' can't closure over the scope it is seemingly defined in... anyway, enough of the gibbering:

This is partially pseudo-code, but I use a variant of it on a Windows Sidebar Gadget (I keep saying this because Sidebar Gadgets run in "unrestricted zone 0", which may -- or may not -- change the scenario greatly.)


// This has to be setup from the main window, not a child/etc!
mainWindow.functionBuilder = function (func, args) {
  // trim the name, if any
  var funcStr = ("" + func).replace(/^function\s+[^\s(]+\s*\(/, "function (")
  try {
    var rebuilt
    eval("rebuilt = (" + funcStr + ")")
    return rebuilt(args)
  } catch (e) {
    alert("oops! " + e.message)
  }
}

// then in the child, as an example
// as stated above, even though function (args) looks like it's 
// a closure in the child scope, IT IS NOT. There you go :)
var x = {blerg: 2}
functionInMainWindowContenxt = mainWindow.functionBuilder(function (args) {
  // in here args is in the bound scope -- have at the child objects! :-/
  function fn (blah) {
    return blah * args.blerg
  }
  return fn
}, x)

x.blerg = 7
functionInMainWindowContext(6) // -> 42 if I did my math right

As a variant, the main window should be able to pass the functionBuilder function to the child window -- as long as the functionBuilder function is defined in the main window context!

I feel like I used too many words. YMMV.


Here's a very specific case in which I've seen this behavior. It is reproducible for me in IE6 and IE7.

From within an iframe:

window.parent.mySpecialHandler = function() { ...work... }

Then, after reloading the iframe with new content, in the window containing the iframe:

window.mySpecialHandler();

This call fails with "Can't execute code from a freed script" because mySpecialHandler was defined in a context (the iframe's original DOM) that no longer exits. (Reloading the iframe destroyed this context.)

You can however safely set "serializeable" values (primitives, object graphs that don't reference functions directly) in the parent window. If you really need a separate window (in my case, an iframe) to specify some work to a remote window, you can pass the work as a String and "eval" it in the receiver. Be careful with this, it generally doesn't make for a clean or secure implementation.