It seems that dev.rubyonrails.org is down at the moment. I think this is the same bug reported in ticket 5228, which was closed with a challenge to create a simple demonstration. I''ll reopen that ticket when I can get to the Trak site. Meanwhile, here''s a demo. Brief summary: when evalScripts is true, PeriodicalUpdater is rendering the scripts as well as executing them. In what seems to be a related problem, it seems to run for one extra iteration after being stopped. Demo Rails code: (View foo.rhtml): <%= link_to_remote "Test Periodical", :url => { :action => "test_periodical"}%> <div id="stuff">Here is some stuff</div> (Controller FooController.rb): def test_periodical logger.info "Called test_periodical" @session[:per] = 1 render :update do |page| page << %Q< if (document.statChecker) { document.statChecker.options.onComplete = undefined; document.statChecker.stop(); } document.statChecker = new Ajax.PeriodicalUpdater(''stuff'',''/ foo/periodical_res'', {asynchronous:true, frequency:2, evalScripts:true }); > end end # http://dev.rubyonrails.org/ticket/5228 def periodical_res logger.info "Called periodical_res" t = @session[:per] if @session[:per] s = "Update number #{t}" @session[:per] = t + 1 if t == 3 render :update do |page| page << %Q{ if (document.statChecker) { document.statChecker.options.onComplete = undefined; document.statChecker.stop(); } } page.replace_html ''stuff'', "All done" end return else render :text => "Update number #{t}" end end end It seems that what''s happening is that the script gets evaluated at line 761 of prototype.js (1.5.0_rc0)(this.evalResponse();), but processing continues through the render. This causes any javascript to be both evaluated and rendered. This can be avoided by making a simple change inrespondToReadyState: respondToReadyState: function(readyState) { var event = Ajax.Request.Events[readyState]; var transport = this.transport, json = this.evalJSON(); var isJS = ((this.header(''Content-type'') || '''').match(/^text\/ javascript/i)) if (event == ''Complete'') { try { (this.options[''on'' + this.transport.status] || this.options[''on'' + (this.responseIsSuccess() ? ''Success'' : ''Failure'')] || Prototype.emptyFunction)(transport, json); } catch (e) { this.dispatchException(e); } if (isJS) { this.evalResponse(); } } if (!isJS) { try { (this.options[''on'' + event] || Prototype.emptyFunction) (transport, json); Ajax.Responders.dispatch(''on'' + event, this, transport, json); } catch (e) { this.dispatchException(e); } } /* Avoid memory leak in MSIE: clean up the oncomplete event handler */ if (event == ''Complete'') this.transport.onreadystatechange = Prototype.emptyFunction; }, As I said, I''ll post a diff in proper form to the Trak site when it''s up again. In the meantime, I''m no Javascript wizard, and would appreciate any comments on my solution or suggestions for a better one. --Al Evans--