GLSL: Shader input not present

I am trying to implement Sean O’Neil’s Atmosphere from space glsl shader, but my shading n00bness ran into a confusing problem, so I add one line of code at a time. When I add a for loop I get AssertionError: Shader input nSamples is not present.
despite having it set in code. Remove the for loop and nSamples suddenly exists.

Vertex shader a2.glsl:

//GLSL
//
// Atmospheric scattering vertex shader
//
// Author: Sean O'Neil
//
// Copyright (c) 2004 Sean O'Neil
//

uniform vec3 v3CameraPos;       // The camera's current position
uniform vec3 v3LightPos;        // The direction vector to the light source
uniform float fOuterRadius;     // The outer (atmosphere) radius
uniform float fOuterRadius2;    // fOuterRadius^2
uniform float fInnerRadius;     

uniform vec3 v3InvWavelength;   // 1 / pow(wavelength, 4) for the red, green, and blue channels

uniform float fScale;           // 1 / (fOuterRadius - fInnerRadius)
uniform float fScaleDepth;      // The scale depth (i.e. the altitude at which the atmosphere's average density is found)
uniform float fScaleOverScaleDepth; // fScale / fScaleDepth

uniform float fKr4PI;           // Kr * 4 * PI
uniform float fKm4PI;           // Km * 4 * PI

uniform float fSamples;
uniform float nSamples;

varying vec3 v3Direction;

float scale(float fCos)
{
    float x = 1.0 - fCos;
    return fScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
    }

void main(void)
{
    // Get the ray from the camera to the vertex and its length (which is the far point of the ray passing through the atmosphere)
    vec3 v3Pos = gl_Vertex.xyz;
    vec3 v3Ray = v3Pos - v3CameraPos;
    float fFar = length(v3Ray);
    v3Ray /= fFar;
    
    // Calculate the closest intersection of the ray with the outer atmosphere (which is the near point of the ray passing through the atmosphere)
    float B = 2.0 * dot(v3CameraPos, v3Ray);
    //float C = fCameraHeight2 - fOuterRadius2;
    float C = 0.0 - fOuterRadius2;
    float fDet = max(0.0, B*B - 4.0 * C);
    float fNear = 0.5 * (-B - sqrt(fDet));
    
    // Calculate the ray's starting position, then calculate its scattering offset
    vec3 v3Start = v3CameraPos + v3Ray * fNear;
    fFar -= fNear;
    float fStartAngle = dot(v3Ray, v3Start) / fOuterRadius;
    float fStartDepth = exp(-1.0 / fScaleDepth);
    float fStartOffset = fStartDepth*scale(fStartAngle);
    
    // Initialize the scattering loop variables
    //gl_FrontColor = vec4(0.0, 0.0, 0.0, 0.0);
    float fSampleLength = fFar / fSamples;
    float fScaledLength = fSampleLength * fScale;
    vec3 v3SampleRay = v3Ray * fSampleLength;
    vec3 v3SamplePoint = v3Start + v3SampleRay * 0.5;
    
    // Now loop through the sample rays
    vec3 v3FrontColor = vec3(0.0, 0.0, 0.0);
    // Next line causes breakage
    for(int i=0; i<nSamples; i++)
    {
        float fHeight = length(v3SamplePoint);
        float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));
        float fLightAngle = dot(v3LightPos, v3SamplePoint) / fHeight;
        float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight;
        float fScatter = (fStartOffset + fDepth*(scale(fLightAngle) - scale(fCameraAngle)));
        vec3 v3Attenuate = exp(-fScatter * (v3InvWavelength * fKr4PI + fKm4PI));
        v3FrontColor += v3Attenuate * (fDepth * fScaledLength);
        v3SamplePoint += v3SampleRay;
        }
    
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    
    v3Direction = 0.0-v3Pos;
}

Temporary Fragment shader a3.glsl

//GLSL
//
// Atmospheric scattering fragment shader
//
// Author: Sean O'Neil
//
// Copyright (c) 2004 Sean O'Neil
//



varying vec3 v3Direction;


void main (void)
{

    }
    
    

And code

self.atmosphere = loader.loadModel("planet_sphere")
            self.atmosphere.setColor(0.5,0.5,1,0.5)
            outerRadius = self.radius + bodyDB['atmosphere']['thickness']
            self.atmosphere.setShaderInput("fOuterRadius", outerRadius)
            self.atmosphere.setShaderInput('fOuterRadius2', outerRadius**2)
            self.atmosphere.setShaderInput("v3CameraPos", 0,0, 0)
            self.atmosphere.setShaderInput("v3LightPos", -149598261, 20000, 0)
            Km = 0.0025 # Mie scattering constant
            ESun = 15.0 # Sun brightness constant
            Kr = 0.0025 #Rayleigh scattering constant
            self.atmosphere.setShaderInput("fKm4PI", Km*4*3.14)
            self.atmosphere.setShaderInput("fKr4PI", Kr*4*3.14)
            self.atmosphere.setShaderInput("fKmESun", Km*ESun)
            self.atmosphere.setShaderInput("fKrESun", Kr*ESun)
            self.atmosphere.setShaderInput("nSamples", 2.0)
            self.atmosphere.setShaderInput("fSamples", 2.0)
            self.atmosphere.setShaderInput('fScale' , 1.0/outerRadius-self.radius)     # 1 / (fOuterRadius - fInnerRadius)
            self.atmosphere.setShaderInput('fScaleDepth' , 0.25)
            self.atmosphere.setShaderInput('fScaleOverScaleDepth' , (1.0/outerRadius-self.radius)/0.25)
            self.atmosphere.setShaderInput('g', -0.95) #;		// The Mie phase asymmetry factor
            self.atmosphere.setShaderInput('g2', -0.95**2)
            m_fWavelength4 = [0,0,0]
            m_fWavelength4[0] = 0.650**4 # 650 nm for red
            m_fWavelength4[1] = 0.570**4 # 570 nm for green
            m_fWavelength4[2] = 0.475**4 # 475 nm for blue
            self.atmosphere.setShaderInput("v3InvWavelength", 1/m_fWavelength4[0], 1/m_fWavelength4[1], 1/m_fWavelength4[2])
            self.atmosphere.setShaderInput('fInnerRadius', float(self.radius))
            self.atmosphere.setShaderInput('fInnerRadius2', float(self.radius)**2)
            self.atmosphere.setShaderInput('fInnerRadius', self.radius**2)
            #atmoShader = Shader.load(Shader.SLGLSL, "AtmoVert.glsl", "AtmoFrag.glsl")
            atmoShader = Shader.load(Shader.SLGLSL, "a2.glsl", "a3.glsl")
            #atmoShader = Shader.load(Shader.SLGLSL, "AtmoFrag.glsl", "AtmoVert.glsl")
            #atmoShader = Shader.load("atmosphere2.cg")
            self.atmosphere.setShader(atmoShader)

see this thread
discourse.panda3d.org/viewtopic.php?t=9264

Might be the same problem and perhaps it’s already fixed in nightly build.