{"record":{"id":"ab12bf6dafb75fec","repo":"commaai/openpilot","slug":"profile-not-found-iccid","errorCode":null,"errorMessage":"profile not found: {iccid}","messagePattern":"profile not found: (.+?)","errorType":"exception","errorClass":"LPAProfileNotFoundError","httpStatus":null,"severity":"error","filePath":"openpilot/common/esim/lpa.py","lineNumber":740,"sourceCode":"          enabled=p.get(\"profileState\") == \"enabled\",\n          provider=p.get(\"serviceProviderName\") or \"\",\n        )\n        for p in list_profiles(self._client)\n      ]\n\n  def get_active_profile(self) -> Profile | None:\n    return None\n\n  def process_notifications(self) -> None:\n    if not system_time_valid():\n      raise RuntimeError(\"System time is not set; TLS certificate validation requires a valid clock\")\n    with self._acquire_channel():\n      process_notifications(self._client)\n\n  def delete_profile(self, iccid: str) -> None:\n    profile = next((p for p in self.list_profiles() if p.iccid == iccid), None)\n    if profile is None:\n      raise LPAProfileNotFoundError(f\"profile not found: {iccid}\")\n    if profile.is_comma:\n      raise LPAError(\"refusing to delete a comma profile\")\n    with self._acquire_channel():\n      request = encode_tlv(TAG_DELETE_PROFILE, encode_tlv(TAG_ICCID, string_to_tbcd(iccid)))\n      response = es10x_command(self._client, request)\n      code = require_tag(require_tag(response, TAG_DELETE_PROFILE, \"DeleteProfileResponse\"), TAG_STATUS, \"DeleteProfile status\")[0]\n    if code != PROFILE_OK:\n      raise LPAError(f\"DeleteProfile failed: {PROFILE_ERROR_CODES.get(code, 'unknown')} (0x{code:02X})\")\n\n  def download_profile(self, qr: str, nickname: str | None = None) -> None:\n    with self._acquire_channel():\n      iccid = download_profile(self._client, qr)\n      if nickname and iccid:\n        set_profile_nickname(self._client, iccid, nickname)\n\n  def nickname_profile(self, iccid: str, nickname: str) -> None:\n    with self._acquire_channel():\n      set_profile_nickname(self._client, iccid, nickname)","sourceCodeStart":722,"sourceCodeEnd":758,"githubUrl":"https://github.com/commaai/openpilot/blob/516ec1e68203439a73f340f1d0b3b91eabc626ee/openpilot/common/esim/lpa.py#L722-L758","documentation":"Lpa.delete_profile(iccid) looks up the requested ICCID in list_profiles(); if no profile matches, it raises LPAProfileNotFoundError with the requested ICCID. It indicates the eUICC has no such profile (or the ICCID string does not exactly match).","triggerScenarios":"Calling delete_profile with an ICCID from a stale cache, a typo, or one whose profile was already deleted; ICCID formatting differences (spaces/check digit) also fail the exact string comparison.","commonSituations":"UI lets the user act on a cached profile list that changed; ICCID copied with separators; profile removed on another device.","solutions":["Call list_profiles() immediately before deleting and pass the exact iccid from that result","Normalize the ICCID (strip spaces/dashes) before comparing","Treat LPAProfileNotFoundError as a benign idempotent delete success where appropriate"],"exampleFix":"// before\ndelete_profile(\"89 00 12 34 ...\")\n\n// after\nprofiles = {p.iccid: p for p in lpa.list_profiles()}\nif iccid in profiles:\n    lpa.delete_profile(iccid)","handlingStrategy":"validation","validationCode":"iccid = iccid.replace(\" \", \"\").replace(\"-\", \"\")\nexists = any(p.iccid == iccid for p in lpa.list_profiles())","typeGuard":null,"tryCatchPattern":"try:\n    lpa.delete_profile(iccid)\nexcept LPAProfileNotFoundError:\n    pass  # already gone — treat as success","preventionTips":["Always derive the ICCID from a fresh list_profiles() call","Treat not-found on delete as idempotent success"],"tags":["esim","lpa","not-found","iccid"],"backgroundTag":null,"analyzedSha":"516ec1e68203439a73f340f1d0b3b91eabc626ee","analyzedAt":"2026-08-15T00:17:37.461Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}