I have been struggling since last few days to resolve this which seems to me should not be an issue.

I have a button on Opportunity page named New Proposal and calling a VF page. This VF page shows the quote list and user is allowed to select and click generate button on this page. The new page render as PDF and has few query strings to use in constructor where I am fetching Opportunity detail.

If I use the QueryString variable and use as below in SOQL, it gives the error of List has no rows for assignment to SObject

String  StrId = (String)ApexPages.currentPage().getParameters().get('id');

Opportunity oPData =[
        Id,Name, account.name, Owner.Name,
        Physical_Address_Street__c, Physical_Address_City__c,
        Physical_Address_State__c, Physical_Address_Zip__c,
        First_Name__c, Last_Name__C
    FROM Opportunity WHERE id = :StrId

If I use a hardcoded value as below, it works fine. Would appreciate any help here.

String  StrId = '0064B000002jHAs';
  • 3
    ... and what is the value of the id parameter in the URL for this page? Is your button correctly passing the ID of the record along to the VF page?
    – Mark Pond
    Feb 12, 2016 at 18:39

2 Answers 2


When you call getParameters, the results are case sensitive. If your parameter is id and you try to get Id, it will fail. Note that if you are implementing a classic extension, you should use the StandardController to get the value instead. For any fields you don't reference in your Visualforce, you need to pass them to the addFields method, which unfortunately cannot be called in a test context. However, if you adopt the following pattern, it is still possible to get 100% code coverage.

public MyExtension(ApexPages.StandardController controller)
    Id recordId = controller.getId();
    List<String> fieldsToQuery = new List<String>
        'Name', 'Account.Name', 'Owner.Name',
        'Physical_Address_Street__c', 'Physical_Address_City__c',
        'Physical_Address_State__c', 'Physical_Address_Zip__c',
        'First_Name__c', 'Last_Name__c'
    if (!Test.isRunningTest()) controller.addFields(fieldsToQuery);
    Opportunity record = (Opportunity)controller.getRecord();

If you are not implementing a classic extension, I would at least make the parameter name into a constant:

public static final String ID_PARAM = 'Id';

public MyController()
    Id recordId = ApexPages.currentPage().getParameters().get(ID_PARAM);
    if (String.isBlank(recordId)) // add page message, throw error, etc.
    Opportunity record = [SELECT fields FROM Opportunity WHERE Id = :recordId];
  • Thanks very much Adrian, I have made the querystring parameter to ID and able to get the value in standard constructor. However, only one addition that I need to do is to use controller.addFields(new String[]{ 'Field 1', 'Field 2' }); Here's the link to the official docs: salesforce.com/us/developer/docs/pages/Content/…
    – anoop jain
    Feb 14, 2016 at 6:02
  • Yes I thought that might be the case, but worried it might clutter the answer. I will add some detail around that when I am in front of a computer again.
    – Adrian Larson
    Feb 14, 2016 at 6:35

You have to get Id parameter not id parameter.

Whenever you create a button of type visualforce page, salesoforce append record Id as a Id parameter.

You must log in to answer this question.

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