I have seen similar behavior in the past, and it's almost always because I'm binding my textures improperly. The most recent incident was caused when I attempted to bind my textures like so:
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, colorTexture);
gl.uniform1i(colorUniform, gl.TEXTURE0);
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, normalTexture);
gl.uniform1i(normalUniform, gl.TEXTURE1);
When the correct syntax is actually:
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, colorTexture);
gl.uniform1i(colorUniform, 0); // 0 to indicate texture unit 0!
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, normalTexture);
gl.uniform1i(normalUniform, 1); // 1 to indicate texture unit 1!
This is a fairly common mistake, and unfortunately WebGL doesn't actually throw an error on the first code snippet (a subject of recent discussion in the WebGL mailing list) and it can appear to work in limited cases, so it's easy to mistakenly think that it's valid code.
I don't know if this is your specific problem, but it's probably the best advice I can provide without further details.