thingsboard/thingsboard · error · ThingsboardException

ITEM_NOT_FOUND

ITEM_NOT_FOUND

Error message

Alarm rule not found

What it means

Thrown by AlarmRuleController helper checkAlarmRule when the referenced CalculatedField exists but its type is not CalculatedFieldType.ALARM. 'Alarm rules' in this version are implemented as calculated fields of type ALARM; passing the ID of a regular (non-alarm) calculated field resolves the entity but fails the type check and reports ITEM_NOT_FOUND.

Source

Thrown at application/src/main/java/org/thingsboard/server/controller/AlarmRuleController.java:254

                .orElse(null);
    }

    @ApiOperation(value = "Test alarm rule TBEL expression (testAlarmRuleScript)",
            notes = TEST_SCRIPT_EXPRESSION + TENANT_AUTHORITY_PARAGRAPH)
    @PreAuthorize("hasAuthority('TENANT_ADMIN')")
    @PostMapping("/alarm/rule/testScript")
    public JsonNode testAlarmRuleScript(
            @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "Test alarm rule TBEL condition expression. The expression must return a boolean value.")
            @RequestBody JsonNode inputParams) throws ThingsboardException {
        checkParameter("expression", inputParams.has("expression") ? inputParams.get("expression").asText() : null);
        return tbCalculatedFieldService.executeTestScript(getTenantId(), inputParams);
    }

    private CalculatedField checkAlarmRule(CalculatedFieldId calculatedFieldId) throws ThingsboardException {
        CalculatedField calculatedField = tbCalculatedFieldService.findById(calculatedFieldId, getCurrentUser());
        checkNotNull(calculatedField);
        if (calculatedField.getType() != CalculatedFieldType.ALARM) {
            throw new ThingsboardException("Alarm rule not found", ThingsboardErrorCode.ITEM_NOT_FOUND);
        }
        return calculatedField;
    }

}

View on GitHub (pinned to 45c30e83fa)

Solutions

  1. Verify the ID with GET /api/calculatedField/{id} and check that type == 'ALARM'; if not, obtain the correct alarm rule ID from the alarm-rules listing endpoint.
  2. If the alarm rule was deleted, recreate it and update the referencing client/dashboard.
  3. Check for ID copy-paste errors between calculated fields and alarm rules in configs or imports.

Example fix

// before
GET /api/alarm/rule/6f8f1a00-... // ID of a plain calculated field -> ITEM_NOT_FOUND "Alarm rule not found"

// after
// list alarm rules and use one whose type is ALARM:
GET /api/alarm/rules?page=0&pageSize=10
GET /api/alarm/rule/<alarmRuleId-with-type-ALARM>
Defensive patterns

Strategy: validation

Validate before calling

// Resolve the ID through the calculated-field API and check the type first:
const cf = await tb.get(`/api/calculatedField/${calculatedFieldId}`);
if (cf.data.type !== 'ALARM') {
  throw new Error(`${calculatedFieldId} is a '${cf.data.type}' calculated field, not an alarm rule`);
}

Type guard

interface CalculatedFieldLike { id?: {id: string}; type?: string }
function isAlarmRule(cf: CalculatedFieldLike | null | undefined): cf is { id: {id: string}; type: 'ALARM' } {
  return !!cf && cf.type === 'ALARM' && !!cf.id?.id;
}

Try / catch

try { return await tb.get(`/api/alarm/rule/${id}`); }
catch (e) {
  if (e.response?.status === 404 && /Alarm rule not found/.test(e.response.data.message)) {
    return await listAlarmRules(); // re-resolve from the authoritative list
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling an alarm-rule endpoint (e.g. GET /api/alarm/rule/{id} or testScript-related flows that go through checkAlarmRule) with the UUID of a calculated field created under /api/calculatedField whose type is SCRIPT or simple.

Common situations: UI state pointing at a stale ID after an alarm rule was deleted and its ID reused by a normal calculated field; scripts mixing IDs from the calculated-field API and the alarm-rule API; importing an entity where the rule reference was remapped incorrectly.

Related errors


AI-assisted analysis of thingsboard/thingsboard@45c30e83fa (2026-08-14). Data as JSON: /api/errors/d83c0f5ab2f101df. Report an issue: GitHub.