Applications Systems
Alert variable ${N=SwisEntity;M=ComponentAlert.StatusOrErrorDescription} is resolving to a raw resource token '@{R=APM.Strings;K=APMSQLDATA_ComponentStatusInformationPrefix;E=SQL}' instead of human‑readable error message in SAM
This article addresses an issue where the StatusOrErrorDescription component alert variable on Windows Service Monitor components resolves to a resource key string (@{R=APM.Strings;K=APMSQLDATA_ComponentStatusInformationPrefix;E=SQL}) instead of a human‑readable status or error message when used in alert actions such as email. The same variable works correctly for other monitor types, such as Windows Event Log Monitor.
First published date
Last published date
Overview
When configuring or simulating an email action for a SAM alert on a Windows Service Monitor or Powershell Script component monitor, the following variable:
${N=SwisEntity;M=ComponentAlert.StatusOrErrorDescription}
resolves to a raw resource token, for example:
@{R=APM.Strings;K=APMSQLDATA_ComponentStatusInformationPrefix;E=SQL}
instead of a descriptive status or error message.
The same variable resolves correctly (human‑readable) when used on other component types such as Windows Event Log Monitor.
Product section
Cause
The behavior is caused by how the StatusOrErrorDescription value is built in the database function [dbo].[apm_GetComponentStatusErrorDescription] for certain evidence types
Resolution
Resolution:
|
Note: The fix for this issue was included in the 2025.2 or later release. Upgrade to 2025.2 or later version to ensure the issue is resolved. |
If you are unable to upgrade to this version, you can try the below workarounds:
Option1: Interim database workaround
-
Stop SolarWinds Platform services
- Diable HA globally ig there's any
-
On the main polling engine, stop all SolarWinds services
- In SQL Server Management Studio (SSMS), connect to the SolarWinds Platform database. Run the SQL script below:
Please coordinate this with your DBA and ensure that you have backup of database before doing manual changes.
-- Scripts are not supported under any SolarWinds support program or service.
-- Scripts are provided AS IS without warranty of any kind. SolarWinds further
-- disclaims all warranties including, without limitation, any implied warranties
-- of merchantability or of fitness for a particular purpose. The risk arising
-- out of the use or performance of the scripts and documentation stays with you.
-- In no event shall SolarWinds or anyone else involved in the creation,
-- production, or delivery of the scripts be liable for any damages whatsoever
-- (including, without limitation, damages for loss of business profits, business
-- interruption, loss of business information, or other pecuniary loss) arising
-- out of the use of or inability to use the scripts or documentation.
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[apm_GetComponentStatusErrorDescription]') AND xtype in (N'FN', N'IF', N'TF'))
DROP FUNCTION [dbo].[apm_GetComponentStatusErrorDescription]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[apm_GetComponentStatusErrorDescription]
(
@Id int,
@EvidenceType int
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE @errorDesc NVARCHAR(MAX);
SET @errorDesc = NULL;
-- port evidence
IF (@EvidenceType = 2)
BEGIN
SELECT @errorDesc = ec.ErrorDescription + coalesce(' ' + sc.StatusDescription, '') + coalesce(' ' + ccs.ErrorMessage, '')
FROM APM_CurrentComponentStatus ccs WITH (NOLOCK)
INNER JOIN APM_PortEvidence_CS_cur pe WITH (NOLOCK)
ON ccs.ComponentStatusID = pe.ComponentStatusID
LEFT JOIN APM_ComponentError_CS_cur ce WITH (NOLOCK)
ON pe.ComponentID = ce.ComponentID AND pe.[Timestamp] = ce.[Timestamp]
LEFT JOIN APM_ErrorCode ec WITH (NOLOCK)
ON ccs.ErrorCode = ec.ID
LEFT JOIN APM_StatusCode sc WITH (NOLOCK)
ON ce.StatusCode = sc.ID AND ce.StatusCodeType = sc.StatusCodeTypeID
WHERE ccs.ComponentID = @Id
END
-- process or dynamic
ELSE IF (@EvidenceType IN (1, 3))
BEGIN
IF EXISTS (SELECT * FROM APM_CurrentComponentStatus WITH (NOLOCK) WHERE ComponentID = @Id AND ErrorCode = 0)
BEGIN
SELECT @errorDesc = REPLACE(N'@{R=APM.Strings;K=APMSQLDATA_ComponentStatusInformationPrefix;E=SQL}','{0}',LOWER(asm.DisplayName)) + coalesce(' ' + ccs.ErrorMessage, '')
FROM APM_CurrentComponentStatus ccs WITH (NOLOCK)
LEFT JOIN dbo.APM_StatusMetadata asm WITH (NOLOCK)
ON asm.ApmStatusValue = ISNULL(ccs.Availability, 0)
WHERE ccs.ComponentID = @Id AND ErrorCode = 0
END
ELSE
BEGIN
SELECT @errorDesc = ec.ErrorDescription + coalesce(' ' + ccs.ErrorMessage, '')
FROM APM_CurrentComponentStatus ccs WITH (NOLOCK)
LEFT JOIN APM_ErrorCode ec WITH (NOLOCK)
ON ccs.ErrorCode = ec.ID
WHERE ccs.ComponentID = @Id
END
END
-- other black box components
IF (@errorDesc IS NULL)
BEGIN
SELECT @errorDesc = asm.DisplayName
FROM dbo.APM_CurrentComponentStatus ccs WITH (NOLOCK)
LEFT JOIN dbo.APM_StatusMetadata asm WITH (NOLOCK)
ON asm.ApmStatusValue = ISNULL(ccs.Availability, 0)
WHERE ccs.ComponentID = @Id
END
return @errorDesc;
END
GO
- Start all SolarWinds services on the main polling engine again.
- Validate
-
-
Re‑run Simulate This Alert on an affected Windows Service Monitor component.
-
Confirm that
${N=SwisEntity;M=ComponentAlert.StatusOrErrorDescription}now shows a readable status/error description instead of@{R=APM.Strings;K=APMSQLDATA_ComponentStatusInformationPrefix;E=SQL}.
-
Option2: Use different Alert Variables:
Use combinations of these variables in the alert email body:
- Component status:
${N=SwisEntity;M=Component.Status}
- Component message
${N=SwisEntity;M=ComponentAlert.ComponentMessage}