6

Question

Is there any known reason a SOQL Query would return a runtime System.QueryException on a custom field in test methods, in particular one one via a parent lookup in a test? I would have thought this is impossible if the apex code compiled. Any one else seeing this sort of behavior?

Background

The simplest case I can get to fail does the following

  1. Creates a test user with specific profile and does a runAs call
  2. Create a Parent__c record with field Fail__c
  3. Create a Child__c record with lookup Parent__c pointing to record from step 2
  4. Query that record
  5. Query Exception?

Code would look like this

static testmethod void feelsLikeImTakingCrazyPills() {
    system.runAs(generateTestUser()) {
        Parent__c parent = new Parent__c(Fail__c = 'wtf');
        insert parent;
        insert new Child__c(Parent__c = parent.Id);
        List<Child__c> children = [SELECT Parent__r.Fail__c FROM Child__c];
        // System.QueryException: No Such Column 'Fail__c' on entity 'Parent__c'
    }
}

Even more bizarre if I don't populate that field, no issue.

static testmethod void feelsLikeImTakingCrazyPills() {
    system.runAs(generateTestUser()) {
        Parent__c parent = new Parent__c(Fail__c = 'wtf');
        insert parent;
        insert new Child__c(Parent__c = null); // <-- i don't populate the lookup here
        List<Child__c> children = [SELECT Parent__r.Fail__c FROM Child__c];
        // no exception
    }
}

And in the actual code that lead to this, the query is in another class. If I make it without sharing no issue.

WTF

Is anyone else seeing this? Seems so confusing:

  • Why would I be able to set a field (in other words it's field level security is read and edit) but not query it?
  • Why would it matter whether I populated the field?
  • Why would without sharing make a difference?
  • Why would a non-dynamic query but not run?
  • Am I alone in experiencing this?

Updates

I'm seeing more strange behavior now in the same vein. Trying to create another object, which the test user's profile has perms for, but when I try and insert it I get DML operation INSERT not allowed, works fine for admin.

4
  • I could swear I came across this same oddity a while back but I can't remember exactly when and what I did to resolve it...
    – NSjonas
    Aug 29, 2014 at 4:44
  • It's weirder now, I'm seeing similar things on DML Operations. Profile has create perms on Object__c, but if I try and insert it I get "DML Operation on Object__c not allowed". Really bizarre Aug 29, 2014 at 7:07
  • probably not related but I was bedeviled by this error and resolved here: cropredysfdc.com/2014/08/01/…
    – cropredy
    Aug 29, 2014 at 23:16
  • @crop1645 nice post, happy to accept if you wanted to summarize in an answer ... Sep 2, 2014 at 23:43

3 Answers 3

6

Ralph -- here is a possible explanation based on a similar experience I had:

If you are generating a SOQL Select in class A using Schema.Describe to get all fields from CustomObject__c resulting in:

Select field1__c, field2__c, field3__c, stdFieldA, stdFieldB  
from CustomOBject__c

Yet, when this query was executed by class B, you get error System.QueryException ‘No such column stdFieldB’

The issue may have to do with versions of each class:

  1. Class A, that generated the SOQL from the Schema.Describe was at VX.0
  2. Class B, that executed the generated SOQL from the Schema.Describe was at VX-n.0
  3. Test Class T, that executed Class A and B was at VX.0

So, the Schema.describe in class A found all the fields known to SFDC version VX.0 which included CustomObject__c.stdFieldB but when executed by a much older class B (version X-n.0), the stdFieldB wasn’t part of the schema at that point in history so QueryException ensued.

Updating class B to VX.0 resolved the issue

Actual use case is blogged here - http://cropredysfdc.com/2014/08/01/versioning-woes-no-such-column-field-is-valid/

1
  • interesting, although in this case, the query isn't dynamic, seems pretty similar otherwise Feb 7, 2015 at 5:08
4

Check the deployment status of the object, if it's not set to Deployed you can get this error. It's confusing since the profile permissions look good, but you can't query the object. Note that you can also avoid this issue by adding without sharing to the class which runs the code in system mode which ignores the deployment status.

Gotcha the error can occur on the detail object of a master/detail relationship if the parent is not deployed, so if the object in question is a child object be sure to go up the hierarchy to look for issue with the deployment status

3
  • Ralph -- thanks for answering this (relatively) old question to help out the Community!
    – cropredy
    Jan 6, 2016 at 2:45
  • 1
    omg @crop1645 this one stumped me forever, so glad to figure it out Jan 7, 2016 at 3:38
  • 1
    Thanks Ralph! I had issues with an object that had been working for years without problems... Only when community users came into play this object could not be found and for the life of me I could not sort it out
    – Steven.B
    Nov 15, 2019 at 13:43
-1

If the user you runAs does not have permissions to the Field, it will throw an error at runtime. However, the apex code (and soql) is still valid which is why the code compiles.

declaring your class as 'without sharing' means that your instance's sharing rules are not enforced

Either fix your sharing rules/permissions or use without sharing.

2
  • 1
    not sure that's the case, for triggers your always in system mode and for vf controllers, the field level security is enforced on the UI side. In any event, the user whose perms we're running with has full perms, and even set the field ... not sure how I can write a field, but not query that same field ... Aug 29, 2014 at 7:06
  • Also, why would the query only fail, if Parent__c is populated, but not otherwise? Aug 29, 2014 at 7:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .