Why do i get this error message?

Empty pointer in fire_bullets: weapon2.frame = 102;

Here is the code:
//////////////////////////////////////////////////////////////////////

var current_ammo = 20;

var player1_pos; // stores the initial position of the player
var player2_pos; // stores the position of the player after a frame

var weapon_height;
var weapon_offset;

var trace_coords;

var got_weapon2 = 0;



string weapon2_mdl = <pistol.mdl>;
bmap cross_map = <crosshair.tga>;
string target_mdl = <target.mdl>;

string muzzle_pcx = <muzzle.pcx>; // muzzle sprite
string explosion_pcx = <explosion+5.pcx>; // explosion sprite
string hithole_tga = <hithole.tga>;

sound bullet_wav = <bullet.wav>;
sound nobullets_wav = <nobullets.wav>;
sound reload_wav = <reload.wav>;

function fire_bullets(); // creates the bullets
function reload();
function display_muzzle();
function explosion_sprite(); // controls the explosion sprite
function show_target(); // displays the (red) target model
function display_hithole(); // shows the hit hole bitmap
function show_crosshair();

panel crosshair
{
layer = 4;
bmap = cross_map;
alpha = 100;
flags = transparent, refresh, overlay, d3d;
}

function show_crosshair()
{
crosshair.pos_x = (screen_size.x - bmap_width(cross_map))/2; //Center on x Axis
crosshair.pos_y = (screen_size.y - bmap_height(cross_map))/2; //Center on y Axis
crosshair.visible = on; //Set crosshair visible
}

/////////////////////////////////////////////////////////////////////////////////////////

entity* weapon2;

function players_weapon()
{
my.znear = on;
my.passable = on;
got_weapon2 = 1;
my.scale_x =4;
my.scale_y =4;
my.scale_z =4;
proc_late();
while (1)
{

vec_set (player1_pos.x, player.x); // store the initial player position
my.pan = camera.pan;
my.tilt = camera.tilt;
vec_set (weapon_offset.x, vector (35, -15, -22));

if (vec_dist (player1_pos.x, player2_pos.x) != 0) // the player has moved during the last frame?
{
weapon_height += 30 * time; // then offset weapon_height (30 = weapon waving speed)
weapon_offset.z += 0.3 * sin(weapon_height); // (0.3 = weapon waving amplitude)
}
// rotate weapon_offset according to the camera angles
vec_rotate (weapon_offset.x, vector (camera.pan, camera.tilt, 0));
vec_add (weapon_offset.x, camera.x); // add the camera position to weapon_offset
vec_set (my.x, weapon_offset.x); // set weapon's coords to weapon_offset
if (got_weapon2 == 1) // still got weapon2 ?
{
on_mouse_left = fire_bullets;

vec_set(trace_coords.x, vector(10000, 0, 0)); // the weapon has a firing range of up to 10,000 quants
vec_rotate(trace_coords.x, camera.pan);
vec_add(trace_coords.x, camera.x);
if (c_trace(camera.x, trace_coords.x, ignore_me | ignore_passable) > 0) // hit something?
{
ent_create (target_mdl, target.x, show_target); // then show the target model
show_crosshair();
}
}
my.pan = camera.pan; // use the same camera angles for the weapon
my.tilt = camera.tilt;
vec_set (player2_pos.x, player.x); // store the new player coordinates after 1 frame
wait (1);
}

}


function show_target()
{
my.passable = on; // the target model is passable
my.ambient = 100; // and should look bright enough
my.scale_x = min (6, vec_dist (my.x, camera.x) / 500); // play with 6 and with 500
my.scale_y = my.scale_x;
my.scale_z = my.scale_x;
wait (1);
ent_remove (my);
}



function fire_bullets()
{
// wait(-0.22); // fire speed
// proc_kill(4); // don't allow more than 1 copy of this function to run

if (current_ammo > 0) // got ammo?
{
c_trace(camera.x, trace_coords.x, ignore_me | ignore_passable | activate_shoot);
if (you == null) // hit a wall?
{
ent_create (hithole_tga, target.x, display_hithole); // then create a bullet hit hole
}

weapon2.frame = 102;
while (weapon2.frame <= 115)
{
weapon2.frame += 3.5 * time_step; //shot animation
wait(1);
}
//
ent_create (muzzle_pcx, temp.x, display_muzzle); // create the gun muzzle
ent_create (explosion_pcx, target.x, explosion_sprite); // create the explosion sprite
snd_play (bullet_wav, 100, 0); // play the bullet sound at a volume of 100

current_ammo -= 1; // decrease the number of bullets
}
else // no ammo left?
{
snd_play (nobullets_wav, 100, 0); // then play the noammo.wav sound

reload();
}

wait(-0.22); // fire speed

}


function display_hithole()
{
vec_to_angle (my.pan, normal); // orient the hit hole sprite correctly
vec_add(my.x, normal.x); // move the sprite a bit away from the wall
my.passable = on; // the hit hole bitmap is passable
my.transparent = on; // and transparent
my.ambient = 50;
my.flare = on;
my.oriented = on; // the sprite is oriented
my.roll = random(360); // and has a random roll angle (looks nicer this way)
my.scale_x = 0.5; // we scale it down
my.scale_y = my.scale_x; // on the x and y axis
sleep (20); // show the hit hole for 20 seconds
ent_remove (my); // and then remove it
}


function display_muzzle()
{
my.passable = on; // the muzzle is passable
my.flare = on; // make the black parts transparent even without using tga files (using a pcx file here)
my.bright = on; // the muzzle should be bright
my.ambient = 100; // and this line makes it even brighter
my.oriented = on; // the sprite is oriented
my.pan = weapon2.pan; // has the same pan and tilt
my.tilt = weapon2.tilt; // with the weapon
my.roll = random(360); // and a random roll angle (looks nicer)
my.scale_x = 0.5; // we scale it down
my.scale_y = my.scale_x; // on all the axis
my.scale_z = my.scale_z; // this would only be needed for a 3D (model-based) muzzle
weapon2.ambient = 100; // highlight the weapon (makes it look more realistic)
wait (2); // show the muzzle sprite for 2 frames
weapon2.ambient = 0; // restore the normal weapon ambient value
ent_remove (my); // and then remove it
}

function explosion_sprite()
{
my.passable = on; // the explosion sprite is passable
my.scale_x = 0.15; // we scale it down to 0.15
my.scale_y = my.scale_x; // on both axis
my.flare = on; // we set its flare
my.bright = on; // and bright flags
my.ambient = 100; // and we give it an ambient of 100
my.roll = random(360); // we set a random roll angle
my.transparent = on; // and make it transparent
my.alpha = 100; // but we set it to be completely opaque for now
while (my.frame < 5) // go through all the animation frames
{
my.frame += 2 * time; // animation speed
wait (1);
}
while (my.alpha > 0) // now fade the last frame quickly
{
my.alpha -= 50 * time; // 50 = fading speed
wait (1);
}
ent_remove (my);
}


function reload()
{
beep;
}


action my_weapon
{
weapon2 = my;
my.passable = on;
while (player == null) {wait (1);}
while (vec_dist (player.x, my.x) > 70)
{
my.pan += 3 * time;
wait (1);
}
ent_remove (my);
ent_create (weapon2_mdl, camera.x, players_weapon);
}