bad argument #-1 Proxy expected, got nil

I have the following error occurring in one of my apps, and I somehow fixed it in a second one, but I am not sure what fixed it.

I just do not understand this error, and was hoping that someone could explain.

From what I have read elsewhere, it has to do with the stack, and reloading/creating objects.

The scenerio for both apps was essentially the same.

I am in a scene, and i go back to the menu.

On both apps i get/got 

bad argument #-1 to ‘newImage’ (Proxy expected, got nil)

On the still broken code, all it is is some buttons, which is why i am confused.   And it makes it to the 3rd button before it errors.

 --Buttons local buttonOne = display.newImage( sceneGroup, "img/button1.png", display.contentCenterX/2, display.contentCenterY + 15) buttonOne.xScale = .9 buttonOne.yScale = .9 local buttonTwo = display.newImage( sceneGroup, "img/button2.png", display.contentCenterX + centerPlus, display.contentCenterY + 15) buttonTwo.xScale = .9 buttonTwo.yScale = .9 local buttonThree = display.newImage( sceneGroup, "img/button3.png", display.contentCenterX/2, display.contentCenterY\*1.6) buttonThree.xScale = .9 buttonThree.yScale = .9 local buttonFour = display.newImage( sceneGroup, "img/button4.png", display.contentCenterX + centerPlus, display.contentCenterY\*1.6) buttonFour.xScale = .9 buttonFour.yScale = .9

I’m not really sure what I am trying to ask… lol

I just need some explanations on this error, so I can learn how to fix it in the future.

The error basically means, Corona expected a display object, but got nil. Are you using Composer? If so, is the code for these buttons in the scene:create function? Aside from the Composer sceneGroup, is there any other part of your code handling the removal of these objects? It looks like one or more of your buttons is being removed, but not recreated. It would help to see more of the code. 

They are not in Create, but in show.

Here is the code for my whole title screen.

local composer = require( "composer" ) local scene = composer.newScene() -- ----------------------------------------------------------------------------------------------------------------- -- All code outside of the listener functions will only be executed ONCE unless "composer.removeScene()" is called. -- ----------------------------------------------------------------------------------------------------------------- -- local forward references should go here --Transition Settings local options = { effect = "crossFade", time = 2000, } centerPlus = display.contentCenterX / 2 -- ------------------------------------------------------------------------------- -- "scene:create()" function scene:create( event ) local sceneGroup = self.view -- Initialize the scene here. -- Example: add display objects to "sceneGroup", add touch listeners, etc. print( "Title Page" ) local bgImage = display.newImage( sceneGroup, "img/bg.png", display.contentCenterX, display.contentHeight, true ) bgImage.xScale = 1.15 bgImage.yScale = 1.15 bgImage.anchorX = .5 bgImage.anchorY = 1 end -- "scene:show()" function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Called when the scene is still off screen (but is about to come on screen). announcement = display.newText( sceneGroup, "This app is still being created. It may still have many bugs. Please report them and any suggestions to thetekbytes@gmail.com Thanks!",0,0, native.systemFont, 10 ) announcement.anchorX = 0 announcement.anchorY = 0 announcement.x = display.contentWidth + 30 announcement.y = 7 elseif ( phase == "did" ) then -- Called when the scene is now on screen. -- Insert code here to make the scene come alive. -- Example: start timers, begin animation, play audio, etc. --Scrolling Text local function textscroll() if (announcement.x \> display.contentWidth) then print( "Marquee Start" ) transition.to( announcement, {time=10000, x=0-(display.contentWidth\*2), y=7} ) elseif (announcement.x \<= 0-display.contentWidth) then print( "resetting marquee" ) transition.to( announcement, {time=0, x= display.contentWidth + 30, y = 7}) else print( "marquee moving" ) end end --Marquee BG local announcementBG = display.newRect( sceneGroup, 0, 7, display.contentWidth, 12 ) announcementBG.anchorX = 0 announcementBG.anchorY = 0 announcementBG.alpha = .25 --Marquee Reset Timer local marqueeResetTimer = timer.performWithDelay( 3000, textscroll, 0 ) --Buttons --slideshow local buttonOne = display.newImage( sceneGroup, "img/button1.png", display.contentCenterX/2, display.contentCenterY + 15) buttonOne.xScale = .9 buttonOne.yScale = .9 --Games local buttonTwo = display.newImage( sceneGroup, "img/button2.png", display.contentCenterX + centerPlus, display.contentCenterY + 15) buttonTwo.xScale = .9 buttonTwo.yScale = .9 --Rewards local buttonThree = display.newImage( sceneGroup, "img/button3.png", display.contentCenterX/2, display.contentCenterY\*1.6) buttonThree.xScale = .9 buttonThree.yScale = .9 --Resources local buttonFour = display.newImage( sceneGroup, "img/button4.png", display.contentCenterX + centerPlus, display.contentCenterY\*1.6) buttonFour.xScale = .9 buttonFour.yScale = .9 function slideshow() print( "slideshow" ) timer.cancel( marqueeResetTimer ) composer.gotoScene( "slideshow" ,options ) end function partygames() print( "partygames" ) end function rewards() print( "rewards" ) timer.cancel( marqueeResetTimer ) composer.gotoScene( "rewards", options ) end function resources() print( "resources" ) end --BUTTON LISTENERS buttonOne:addEventListener( "tap", slideshow ) buttonTwo:addEventListener( "tap", partygames ) buttonThree:addEventListener( "tap", rewards ) buttonFour:addEventListener( "tap", resources ) end end -- "scene:hide()" function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Called when the scene is on screen (but is about to go off screen). -- Insert code here to "pause" the scene. -- Example: stop timers, stop animation, stop audio, etc. elseif ( phase == "did" ) then -- Called immediately after scene goes off screen. end end -- "scene:destroy()" function scene:destroy( event ) local sceneGroup = self.view -- Called prior to the removal of scene's view ("sceneGroup"). -- Insert code here to clean up the scene. -- Example: remove display objects, save state, etc. end -- ------------------------------------------------------------------------------- -- Listener setup scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) -- ------------------------------------------------------------------------------- return scene

I would check to see that filename for ‘button3.png’ is spelled the same and has the same ‘case’ as you have it in the code.  If you are correct when you say, ‘makes it to the 3rd button before it errors’, I assume you mean the code above the 3rd button code executes without error,  and as the code for the first 2 buttons is identical to the code for button3, the filename is what I would look at first.  So go to the ‘img’ directory in your app and see that that image is indeed there and it’s spelling and case sensitivity is the same as in the code.

It is a little confusing to me that you say when you ‘go back to the menu’, as to imply that the scene you are having issue with loaded correctly … which would mean that the filename would have to be correct in order for the problem scene to have ‘shown’ initially.  But, I it does not make sense to have the code process the identical code for the first 2 buttons correctly and not the 3rd, other then for the reason I mentioned … ‘filename conflict’

I hope this helps.

Look in your console log.  There is probably a warning saying it can’t find button3.png. 

Rob

I have to mention that I am a silly goose, and was looking in the wrong file the whole time.

I realized it as i was looking for the button picture.

The error is coming from a timer trying to effect an object deleted during the transition back to the menu.

now the problem is, it’s not accepting timer.cancel(timer)  even though i added it to the  “Will Hide” portion of code.

Perhaps I missed something. My understanding of Composer is that display objects need to be added to the sceneGroup in scene:create, not scene:show. You are adding your display objects to the scene in the ‘did’ phase of scene:show, which means they aren’t actually being processed until the scene is already on the screen.  Generally speaking, you would want your display object code already processed so when scene:show is called, the objects are on the screen. Regardless, if you add display objects to the sceneGroup in any method other than scene:create, I don’t believe they will be handled appropriately when the scene is removed. Anyone else??

@james

You may be correct on this?

There is actually a line in the composer template that says so.

– Initialize the scene here.
– Example: add display objects to “sceneGroup”, add touch listeners, etc.

I will move everything to the correct position after while, and see if that fixes my issue.

The error basically means, Corona expected a display object, but got nil. Are you using Composer? If so, is the code for these buttons in the scene:create function? Aside from the Composer sceneGroup, is there any other part of your code handling the removal of these objects? It looks like one or more of your buttons is being removed, but not recreated. It would help to see more of the code. 

They are not in Create, but in show.

Here is the code for my whole title screen.

local composer = require( "composer" ) local scene = composer.newScene() -- ----------------------------------------------------------------------------------------------------------------- -- All code outside of the listener functions will only be executed ONCE unless "composer.removeScene()" is called. -- ----------------------------------------------------------------------------------------------------------------- -- local forward references should go here --Transition Settings local options = { effect = "crossFade", time = 2000, } centerPlus = display.contentCenterX / 2 -- ------------------------------------------------------------------------------- -- "scene:create()" function scene:create( event ) local sceneGroup = self.view -- Initialize the scene here. -- Example: add display objects to "sceneGroup", add touch listeners, etc. print( "Title Page" ) local bgImage = display.newImage( sceneGroup, "img/bg.png", display.contentCenterX, display.contentHeight, true ) bgImage.xScale = 1.15 bgImage.yScale = 1.15 bgImage.anchorX = .5 bgImage.anchorY = 1 end -- "scene:show()" function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Called when the scene is still off screen (but is about to come on screen). announcement = display.newText( sceneGroup, "This app is still being created. It may still have many bugs. Please report them and any suggestions to thetekbytes@gmail.com Thanks!",0,0, native.systemFont, 10 ) announcement.anchorX = 0 announcement.anchorY = 0 announcement.x = display.contentWidth + 30 announcement.y = 7 elseif ( phase == "did" ) then -- Called when the scene is now on screen. -- Insert code here to make the scene come alive. -- Example: start timers, begin animation, play audio, etc. --Scrolling Text local function textscroll() if (announcement.x \> display.contentWidth) then print( "Marquee Start" ) transition.to( announcement, {time=10000, x=0-(display.contentWidth\*2), y=7} ) elseif (announcement.x \<= 0-display.contentWidth) then print( "resetting marquee" ) transition.to( announcement, {time=0, x= display.contentWidth + 30, y = 7}) else print( "marquee moving" ) end end --Marquee BG local announcementBG = display.newRect( sceneGroup, 0, 7, display.contentWidth, 12 ) announcementBG.anchorX = 0 announcementBG.anchorY = 0 announcementBG.alpha = .25 --Marquee Reset Timer local marqueeResetTimer = timer.performWithDelay( 3000, textscroll, 0 ) --Buttons --slideshow local buttonOne = display.newImage( sceneGroup, "img/button1.png", display.contentCenterX/2, display.contentCenterY + 15) buttonOne.xScale = .9 buttonOne.yScale = .9 --Games local buttonTwo = display.newImage( sceneGroup, "img/button2.png", display.contentCenterX + centerPlus, display.contentCenterY + 15) buttonTwo.xScale = .9 buttonTwo.yScale = .9 --Rewards local buttonThree = display.newImage( sceneGroup, "img/button3.png", display.contentCenterX/2, display.contentCenterY\*1.6) buttonThree.xScale = .9 buttonThree.yScale = .9 --Resources local buttonFour = display.newImage( sceneGroup, "img/button4.png", display.contentCenterX + centerPlus, display.contentCenterY\*1.6) buttonFour.xScale = .9 buttonFour.yScale = .9 function slideshow() print( "slideshow" ) timer.cancel( marqueeResetTimer ) composer.gotoScene( "slideshow" ,options ) end function partygames() print( "partygames" ) end function rewards() print( "rewards" ) timer.cancel( marqueeResetTimer ) composer.gotoScene( "rewards", options ) end function resources() print( "resources" ) end --BUTTON LISTENERS buttonOne:addEventListener( "tap", slideshow ) buttonTwo:addEventListener( "tap", partygames ) buttonThree:addEventListener( "tap", rewards ) buttonFour:addEventListener( "tap", resources ) end end -- "scene:hide()" function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Called when the scene is on screen (but is about to go off screen). -- Insert code here to "pause" the scene. -- Example: stop timers, stop animation, stop audio, etc. elseif ( phase == "did" ) then -- Called immediately after scene goes off screen. end end -- "scene:destroy()" function scene:destroy( event ) local sceneGroup = self.view -- Called prior to the removal of scene's view ("sceneGroup"). -- Insert code here to clean up the scene. -- Example: remove display objects, save state, etc. end -- ------------------------------------------------------------------------------- -- Listener setup scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) -- ------------------------------------------------------------------------------- return scene

I would check to see that filename for ‘button3.png’ is spelled the same and has the same ‘case’ as you have it in the code.  If you are correct when you say, ‘makes it to the 3rd button before it errors’, I assume you mean the code above the 3rd button code executes without error,  and as the code for the first 2 buttons is identical to the code for button3, the filename is what I would look at first.  So go to the ‘img’ directory in your app and see that that image is indeed there and it’s spelling and case sensitivity is the same as in the code.

It is a little confusing to me that you say when you ‘go back to the menu’, as to imply that the scene you are having issue with loaded correctly … which would mean that the filename would have to be correct in order for the problem scene to have ‘shown’ initially.  But, I it does not make sense to have the code process the identical code for the first 2 buttons correctly and not the 3rd, other then for the reason I mentioned … ‘filename conflict’

I hope this helps.

Look in your console log.  There is probably a warning saying it can’t find button3.png. 

Rob

I have to mention that I am a silly goose, and was looking in the wrong file the whole time.

I realized it as i was looking for the button picture.

The error is coming from a timer trying to effect an object deleted during the transition back to the menu.

now the problem is, it’s not accepting timer.cancel(timer)  even though i added it to the  “Will Hide” portion of code.

Perhaps I missed something. My understanding of Composer is that display objects need to be added to the sceneGroup in scene:create, not scene:show. You are adding your display objects to the scene in the ‘did’ phase of scene:show, which means they aren’t actually being processed until the scene is already on the screen.  Generally speaking, you would want your display object code already processed so when scene:show is called, the objects are on the screen. Regardless, if you add display objects to the sceneGroup in any method other than scene:create, I don’t believe they will be handled appropriately when the scene is removed. Anyone else??

@james

You may be correct on this?

There is actually a line in the composer template that says so.

– Initialize the scene here.
– Example: add display objects to “sceneGroup”, add touch listeners, etc.

I will move everything to the correct position after while, and see if that fixes my issue.