{"record":{"id":"3d9aa7ab3a18baeb","repo":"pentaho/pentaho-kettle","slug":"salesforcedelete-error-deletekeyfieldmissing","errorCode":null,"errorMessage":"SalesforceDelete.Error.DeleteKeyFieldMissing","messagePattern":"SalesforceDelete\\.Error\\.DeleteKeyFieldMissing","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"plugins/salesforce/core/src/main/java/org/pentaho/di/trans/steps/salesforcedelete/SalesforceDelete.java","lineNumber":75,"sourceCode":"      return false;\n    }\n\n    // If we haven't looked at a row before then do some basic setup.\n    if ( first ) {\n      first = false;\n\n      data.deleteId = new String[meta.getBatchSizeInt()];\n      data.outputBuffer = new Object[meta.getBatchSizeInt()][];\n\n      // Create the output row meta-data\n      data.outputRowMeta = getInputRowMeta().clone();\n      meta.getFields( getTransMeta().getBowl(), data.outputRowMeta, getStepname(), null, null, this, repository,\n                      metaStore );\n\n      // Check deleteKeyField\n      String realFieldName = environmentSubstitute( meta.getDeleteField() );\n      if ( Utils.isEmpty( realFieldName ) ) {\n        throw new KettleException( BaseMessages.getString( PKG, \"SalesforceDelete.Error.DeleteKeyFieldMissing\" ) );\n      }\n\n      // return the index of the field in the input stream\n      data.indexOfKeyField = getInputRowMeta().indexOfValue( realFieldName );\n      if ( data.indexOfKeyField < 0 ) {\n        // the field is unreachable!\n        throw new KettleException( BaseMessages.getString(\n          PKG, \"SalesforceDelete.Error.CanNotFindFDeleteKeyField\", realFieldName ) );\n      }\n    }\n\n    try {\n      writeToSalesForce( outputRowData );\n    } catch ( Exception e ) {\n      throw new KettleStepException( BaseMessages.getString( PKG, \"SalesforceDelete.log.Exception\" ), e );\n    }\n    return true;\n  }","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/salesforce/core/src/main/java/org/pentaho/di/trans/steps/salesforcedelete/SalesforceDelete.java#L57-L93","documentation":"SalesforceDelete.processRow validates that the step's delete key field is configured before deleting records from Salesforce. If the 'DeleteField' setting is empty or resolves to an empty string after variable substitution, the step cannot know which input field contains the record IDs to delete, so it aborts with this KettleException.","triggerScenarios":"Running a Salesforce Delete transformation step whose 'Key field' (deleteField) property is blank, or contains only a variable reference that resolves to empty at runtime.","commonSituations":"A transformation copied or re-created without filling in the key field; environment variable not defined so environmentSubstitute returns empty; step exported/imported without the field persisted.","solutions":["Open the Salesforce Delete step dialog and set the 'Key field' property to the input field containing the IDs","Verify the variable used in the field setting is actually defined in the runtime environment (kettle.properties, parameters)","Re-save the transformation to ensure the DeleteField attribute is persisted","Add a check in the transformation's initialization (or a Get Variables step) to validate the variable resolves to a non-empty value"],"exampleFix":"// before: step meta with empty delete field\nmeta.setDeleteField(\"\");\n// after\nmeta.setDeleteField(\"Id\"); // or \"${SF_DELETE_KEY_FIELD}\" with the variable defined in kettle.properties","handlingStrategy":"validation","validationCode":"// before executing the transformation\nString realFieldName = environmentSubstitute(meta.getDeleteField());\nif (realFieldName == null || realFieldName.trim().isEmpty()) {\n  throw new IllegalStateException(\"Salesforce Delete step: key field (DeleteField) is not set\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  executeTransformation();\n} catch (KettleException e) {\n  if (e.getMessage().contains(\"DeleteKeyFieldMissing\")) {\n    logError(\"Configure the Salesforce Delete step's 'Key field' before running\");\n  }\n  throw e;\n}","preventionTips":["Always set the 'Key field' in the Salesforce Delete step dialog","Avoid bare ${VARIABLE} references unless the variable is guaranteed defined in kettle.properties or parameters","Use the step's Check/Verify button to catch missing settings before runtime","Template transformations with the key field pre-filled"],"tags":["salesforce","delete","missing-field","configuration"],"backgroundTag":"missing-required-config-field","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}